1 | <?php |
---|
2 | /*! |
---|
3 | * HybridAuth |
---|
4 | * http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth |
---|
5 | * (c) 2009-2012, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html |
---|
6 | */ |
---|
7 | |
---|
8 | // A service client for the OAuth 2 flow. |
---|
9 | // v0.1 |
---|
10 | class OAuth2Client |
---|
11 | { |
---|
12 | public $api_base_url = ""; |
---|
13 | public $authorize_url = ""; |
---|
14 | public $token_url = ""; |
---|
15 | public $token_info_url = ""; |
---|
16 | |
---|
17 | public $client_id = "" ; |
---|
18 | public $client_secret = "" ; |
---|
19 | public $redirect_uri = "" ; |
---|
20 | public $access_token = "" ; |
---|
21 | public $refresh_token = "" ; |
---|
22 | |
---|
23 | public $access_token_expires_in = "" ; |
---|
24 | public $access_token_expires_at = "" ; |
---|
25 | |
---|
26 | //-- |
---|
27 | |
---|
28 | public $sign_token_name = "access_token"; |
---|
29 | public $decode_json = true; |
---|
30 | public $curl_time_out = 30; |
---|
31 | public $curl_connect_time_out = 30; |
---|
32 | public $curl_ssl_verifypeer = false; |
---|
33 | public $curl_header = array(); |
---|
34 | public $curl_useragent = "OAuth/2 Simple PHP Client v0.1; HybridAuth http://hybridauth.sourceforge.net/"; |
---|
35 | public $curl_authenticate_method = "POST"; |
---|
36 | public $curl_proxy = null; |
---|
37 | |
---|
38 | //-- |
---|
39 | |
---|
40 | public $http_code = ""; |
---|
41 | public $http_info = ""; |
---|
42 | |
---|
43 | //-- |
---|
44 | |
---|
45 | public function __construct( $client_id = false, $client_secret = false, $redirect_uri='' ) |
---|
46 | { |
---|
47 | $this->client_id = $client_id; |
---|
48 | $this->client_secret = $client_secret; |
---|
49 | $this->redirect_uri = $redirect_uri; |
---|
50 | } |
---|
51 | |
---|
52 | public function authorizeUrl( $extras = array() ) |
---|
53 | { |
---|
54 | $params = array( |
---|
55 | "client_id" => $this->client_id, |
---|
56 | "redirect_uri" => $this->redirect_uri, |
---|
57 | "response_type" => "code" |
---|
58 | ); |
---|
59 | |
---|
60 | if( count($extras) ) |
---|
61 | foreach( $extras as $k=>$v ) |
---|
62 | $params[$k] = $v; |
---|
63 | |
---|
64 | return $this->authorize_url . "?" . http_build_query( $params ); |
---|
65 | } |
---|
66 | |
---|
67 | public function authenticate( $code ) |
---|
68 | { |
---|
69 | $params = array( |
---|
70 | "client_id" => $this->client_id, |
---|
71 | "client_secret" => $this->client_secret, |
---|
72 | "grant_type" => "authorization_code", |
---|
73 | "redirect_uri" => $this->redirect_uri, |
---|
74 | "code" => $code |
---|
75 | ); |
---|
76 | |
---|
77 | $response = $this->request( $this->token_url, $params, $this->curl_authenticate_method ); |
---|
78 | |
---|
79 | $response = $this->parseRequestResult( $response ); |
---|
80 | |
---|
81 | if( ! $response || ! isset( $response->access_token ) ){ |
---|
82 | throw new Exception( "The Authorization Service has return: " . $response->error ); |
---|
83 | } |
---|
84 | |
---|
85 | if( isset( $response->access_token ) ) $this->access_token = $response->access_token; |
---|
86 | if( isset( $response->refresh_token ) ) $this->refresh_token = $response->refresh_token; |
---|
87 | if( isset( $response->expires_in ) ) $this->access_token_expires_in = $response->expires_in; |
---|
88 | |
---|
89 | // calculate when the access token expire |
---|
90 | if( isset($response->expires_in)) { |
---|
91 | $this->access_token_expires_at = time() + $response->expires_in; |
---|
92 | } |
---|
93 | |
---|
94 | return $response; |
---|
95 | } |
---|
96 | |
---|
97 | public function authenticated() |
---|
98 | { |
---|
99 | if ( $this->access_token ){ |
---|
100 | if ( $this->token_info_url && $this->refresh_token ){ |
---|
101 | // check if this access token has expired, |
---|
102 | $tokeninfo = $this->tokenInfo( $this->access_token ); |
---|
103 | |
---|
104 | // if yes, access_token has expired, then ask for a new one |
---|
105 | if( $tokeninfo && isset( $tokeninfo->error ) ){ |
---|
106 | $response = $this->refreshToken( $this->refresh_token ); |
---|
107 | |
---|
108 | // if wrong response |
---|
109 | if( ! isset( $response->access_token ) || ! $response->access_token ){ |
---|
110 | throw new Exception( "The Authorization Service has return an invalid response while requesting a new access token. given up!" ); |
---|
111 | } |
---|
112 | |
---|
113 | // set new access_token |
---|
114 | $this->access_token = $response->access_token; |
---|
115 | } |
---|
116 | } |
---|
117 | |
---|
118 | return true; |
---|
119 | } |
---|
120 | |
---|
121 | return false; |
---|
122 | } |
---|
123 | |
---|
124 | /** |
---|
125 | * Format and sign an oauth for provider api |
---|
126 | */ |
---|
127 | public function api( $url, $method = "GET", $parameters = array() ) |
---|
128 | { |
---|
129 | if ( strrpos($url, 'http://') !== 0 && strrpos($url, 'https://') !== 0 ) { |
---|
130 | $url = $this->api_base_url . $url; |
---|
131 | } |
---|
132 | |
---|
133 | $parameters[$this->sign_token_name] = $this->access_token; |
---|
134 | $response = null; |
---|
135 | |
---|
136 | switch( $method ){ |
---|
137 | case 'GET' : $response = $this->request( $url, $parameters, "GET" ); break; |
---|
138 | case 'POST' : $response = $this->request( $url, $parameters, "POST" ); break; |
---|
139 | } |
---|
140 | |
---|
141 | if( $response && $this->decode_json ){ |
---|
142 | $response = json_decode( $response ); |
---|
143 | } |
---|
144 | |
---|
145 | return $response; |
---|
146 | } |
---|
147 | |
---|
148 | /** |
---|
149 | * GET wrappwer for provider apis request |
---|
150 | */ |
---|
151 | function get( $url, $parameters = array() ) |
---|
152 | { |
---|
153 | return $this->api( $url, 'GET', $parameters ); |
---|
154 | } |
---|
155 | |
---|
156 | /** |
---|
157 | * POST wreapper for provider apis request |
---|
158 | */ |
---|
159 | function post( $url, $parameters = array() ) |
---|
160 | { |
---|
161 | return $this->api( $url, 'POST', $parameters ); |
---|
162 | } |
---|
163 | |
---|
164 | // -- tokens |
---|
165 | |
---|
166 | public function tokenInfo($accesstoken) |
---|
167 | { |
---|
168 | $params['access_token'] = $this->access_token; |
---|
169 | $response = $this->request( $this->token_info_url, $params ); |
---|
170 | return $this->parseRequestResult( $response ); |
---|
171 | } |
---|
172 | |
---|
173 | public function refreshToken( $parameters = array() ) |
---|
174 | { |
---|
175 | $params = array( |
---|
176 | "client_id" => $this->client_id, |
---|
177 | "client_secret" => $this->client_secret, |
---|
178 | "grant_type" => "refresh_token" |
---|
179 | ); |
---|
180 | |
---|
181 | foreach($parameters as $k=>$v ){ |
---|
182 | $params[$k] = $v; |
---|
183 | } |
---|
184 | |
---|
185 | $response = $this->request( $this->token_url, $params, "POST" ); |
---|
186 | return $this->parseRequestResult( $response ); |
---|
187 | } |
---|
188 | |
---|
189 | // -- utilities |
---|
190 | |
---|
191 | private function request( $url, $params=false, $type="GET" ) |
---|
192 | { |
---|
193 | Hybrid_Logger::info( "Enter OAuth2Client::request( $url )" ); |
---|
194 | Hybrid_Logger::debug( "OAuth2Client::request(). dump request params: ", serialize( $params ) ); |
---|
195 | |
---|
196 | if( $type == "GET" ){ |
---|
197 | $url = $url . ( strpos( $url, '?' ) ? '&' : '?' ) . http_build_query( $params ); |
---|
198 | } |
---|
199 | |
---|
200 | $this->http_info = array(); |
---|
201 | $ch = curl_init(); |
---|
202 | |
---|
203 | curl_setopt($ch, CURLOPT_URL , $url ); |
---|
204 | curl_setopt($ch, CURLOPT_RETURNTRANSFER , 1 ); |
---|
205 | curl_setopt($ch, CURLOPT_TIMEOUT , $this->curl_time_out ); |
---|
206 | curl_setopt($ch, CURLOPT_USERAGENT , $this->curl_useragent ); |
---|
207 | curl_setopt($ch, CURLOPT_CONNECTTIMEOUT , $this->curl_connect_time_out ); |
---|
208 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER , $this->curl_ssl_verifypeer ); |
---|
209 | curl_setopt($ch, CURLOPT_HTTPHEADER , $this->curl_header ); |
---|
210 | |
---|
211 | if($this->curl_proxy){ |
---|
212 | curl_setopt( $ch, CURLOPT_PROXY , $this->curl_proxy); |
---|
213 | } |
---|
214 | |
---|
215 | if( $type == "POST" ){ |
---|
216 | curl_setopt($ch, CURLOPT_POST, 1); |
---|
217 | if($params) curl_setopt( $ch, CURLOPT_POSTFIELDS, $params ); |
---|
218 | } |
---|
219 | |
---|
220 | $response = curl_exec($ch); |
---|
221 | Hybrid_Logger::debug( "OAuth2Client::request(). dump request info: ", serialize( curl_getinfo($ch) ) ); |
---|
222 | Hybrid_Logger::debug( "OAuth2Client::request(). dump request result: ", serialize( $response ) ); |
---|
223 | |
---|
224 | $this->http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); |
---|
225 | $this->http_info = array_merge($this->http_info, curl_getinfo($ch)); |
---|
226 | |
---|
227 | curl_close ($ch); |
---|
228 | |
---|
229 | return $response; |
---|
230 | } |
---|
231 | |
---|
232 | private function parseRequestResult( $result ) |
---|
233 | { |
---|
234 | if( json_decode( $result ) ) return json_decode( $result ); |
---|
235 | |
---|
236 | parse_str( $result, $ouput ); |
---|
237 | |
---|
238 | $result = new StdClass(); |
---|
239 | |
---|
240 | foreach( $ouput as $k => $v ) |
---|
241 | $result->$k = $v; |
---|
242 | |
---|
243 | return $result; |
---|
244 | } |
---|
245 | } |
---|