Skip to content

Commit 350fd01

Browse files
committed
Merge branch 'develop'
2 parents b773555 + 45ce968 commit 350fd01

File tree

8 files changed

+475
-330
lines changed

8 files changed

+475
-330
lines changed

README.md

Lines changed: 89 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,17 @@ This SDK allows you to use OAuth.io's server-side flow from a PHP backend, to ha
77

88
You can use it with one of our front-end SDKs ([JavaScript][1], [PhoneGap][2], [iOs][3], [Android][4]), which will handle the user input for the OAuth flow.
99

10-
This SDK is still under heavy development and some of the features described below may not work yet. You can get nightlies from the [develop branch](https://github.com/oauth-io/sdk-php/tree/develop) on the SDK's github page.
10+
The current version of the SDK is `0.2.0`. Older versions are deprecated.
1111

12-
A release will be posted soon.
12+
You can also get nightlies by checking out our `develop` branch.
13+
14+
Features
15+
--------
16+
17+
- Server-side OAuth authentication flow
18+
- Requests to API from the backend
19+
- Unified user information (`.me()` method) requests when available
20+
- Access token renewal with the refresh_token when available
1321

1422
Common use-Case
1523
---------------
@@ -30,15 +38,17 @@ To authenticate a user, the flow follows these steps :
3038
- oauth.io responds with the access_token, that you can then store on your backend as long as it's valid
3139
- You can then make requests to the API using that access token, directly from your backend
3240

41+
As of `0.2.0` it is possible to get an automatically refreshed access token when a refresh token is available.
42+
3343
Installation
3444
------------
3545

36-
You will soon be able to install it through Composer by adding the following dependency to your composer.json :
46+
You can install it through Composer by adding the following dependency to your composer.json :
3747

3848
```json
3949
"require": {
4050
...
41-
"oauth-io/oauth": "0.1.0"
51+
"oauth-io/oauth": "0.2.0"
4252
...
4353
},
4454
```
@@ -126,24 +136,36 @@ You have to give this token to your front-end, where you can show the user a pop
126136

127137
**Auth the user**
128138

129-
To be able to make requests to a provider's API using its access token, you have to call the `auth(code)` method. The code is retrieved from OAuth.io through the from the front-end SDK (see further down). You need to create an endpoint to allow the front-end to send it to the backend.
139+
To be able to make requests to a provider's API using its access token, you have to call the `auth(provider, options)` method first. This method creates a request object from either a code you got from the front-end SDK (for the first time authentication), the session (if the user was authenticated during the same session), or a credentials array that you saved earlier.
130140

131-
Once you have that code, you can call the method like this :
141+
To get a request object from a code (which automatically fills up the session for further use in other endpoints), you can do like this :
132142

133143
```php
134-
$result = $oauth->auth($code);
144+
$request_object = $oauth->auth('the_provider', array(
145+
'code': $code
146+
));
135147
```
136148

137-
`$result` is an array containing the access token, which you can use your own way if you want, or thanks to the SDK's request system (see further down).
149+
`$request_object` is an object that allows you to perform requests (see further down to learn how to), and that contains the user's credentials.
138150

139-
**Retrieving the code from the front-end**
151+
You can get the credentials array if you need to save them for later use (or for a cron) like this :
152+
153+
```php
154+
$credentials = $request_object->getCredentials();
155+
```
156+
157+
The `$credentials` array contains the access token, refresh token and other information returned by the provider.
158+
159+
**Retrieving a code from the front-end**
140160

141161
```JavaScript
142162
//In the front end, using the JavaScript SDK :
143163

144164
OAuth.initialize('your_key');
145165
OAuth.popup('a_provider', {
146-
state: 'the_token_retrieved_from_your_backend'
166+
// The state token you got from the backend
167+
// through $oauth->generateStateToken():
168+
state: 'state_token'
147169
})
148170
.done(function (r) {
149171
//You need to give r.code to your backend
@@ -162,15 +184,7 @@ OAuth.popup('a_provider', {
162184

163185
**Making requests to the API**
164186

165-
Once the user is authenticated, you can create a request object from the SDK `create('provider')` method :
166-
167-
```php
168-
<?php
169-
$request_object = $oauth->create('some_provider');
170-
//?>
171-
```
172-
173-
Then, you can make get, post, put, delete and patch requests to the API like this :
187+
Once you have a request object, you can make requests to the API.
174188

175189
```php
176190
<?php
@@ -196,6 +210,52 @@ $result = $facebook_requester->me(array('firstname', 'lastname', 'email'));
196210

197211
You can refer to the OAuth.io me() feature to get more information about the fields that are returned by this method.
198212

213+
**Using the session**
214+
215+
Usually, you'll want to make calls to the API several times while the user is connected to your app. Once you've authenticated the user once with a code, the session is automatically configured to work with the SDK.
216+
217+
Thus, you just need to do this to get a request object:
218+
219+
```php
220+
$request_object = $oauth->auth('the_provider');
221+
```
222+
223+
**Saving credentials**
224+
225+
You can also save the user's credentials to make requests in a cron. You can get the credentials array from a request object like this :
226+
227+
```php
228+
$credentials = $request_object->getCredentials();
229+
// Here save the $credentials array for later use
230+
```
231+
232+
233+
Then, when you want to reuse these credentials, you can rebuild a $request_object from them:
234+
235+
```php
236+
$request_object = $oauth->auth('the_provider', array(
237+
'credentials' => $credentials
238+
));
239+
```
240+
241+
**Refreshing the token**
242+
243+
If a refresh token is available and the access token is expired, the `auth` method will automatically use that refresh token to get a new access token.
244+
245+
You can force the renewal by passing the `force_refresh` field in the options array:
246+
247+
```php
248+
$request_object = $oauth->auth('the_provider', array(
249+
'credentials' => $credentials,
250+
'force_refresh' => true
251+
));
252+
```
253+
254+
You can also directly refresh a credentials array like this:
255+
256+
```php
257+
$refreshed_credentials = $oauth->refreshCredentials($old_credentials);
258+
```
199259

200260
Contributing to this SDK
201261
------------------------
@@ -206,7 +266,16 @@ Please discuss issues and features on Github Issues. We'll be happy to answer to
206266

207267
**Pull requests**
208268

209-
You are welcome to fork this SDK and to make pull requests on Github. We'll review each of them, and integrate in a future release if they are relevant.
269+
You are welcome to fork and make pull requests. We appreciate the time you spend working on this project and we will be happy to review your code and merge it if it brings nice improvements :)
270+
271+
If you want to do a pull request, please mind these simple rules :
272+
273+
- *One feature per pull request*
274+
- *Write clear commit messages*
275+
- *Unit test your feature* : if it's a bug fix for example, write a test that proves the bug exists and that your fix resolves it.
276+
- *Write a clear description of the pull request*
277+
278+
If you do so, we'll be able to merge your pull request more quickly :)
210279

211280
The SDK is written as a Composer module. You can install its dependencies like this :
212281

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "oauth-io/oauth",
33
"description": "OAuth that just works !",
44
"license": "Apache2",
5-
"version": "0.1.0",
5+
"version": "0.2.0",
66
"authors": [
77
{
88
"name": "oauth-io",

src/OAuth_io/HttpWrapper.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ public function make_request($options) {
2828
$qs = http_build_query($options['qs']);
2929
$url.= '?' . $qs;
3030
}
31+
$url = str_replace('%2C', ',', $url);
32+
3133
\Unirest::verifyPeer($injector->ssl_verification);
3234
if ($options['method'] == 'GET') {
3335
$response = \Unirest::get($url, $headers);

src/OAuth_io/OAuth.php

Lines changed: 77 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,24 @@ class OAuth {
1010
*
1111
*
1212
*/
13-
public function __construct(&$session = null, $ssl_verification = true) {
13+
public function __construct() {
1414
$this->injector = Injector::getInstance();
15+
}
16+
17+
/**
18+
*
19+
*/
20+
public function setSslVerification($ssl_verification) {
21+
$this->injector->ssl_verification = $ssl_verification;
22+
}
23+
24+
/**
25+
*
26+
*/
27+
public function setSession(&$session) {
1528
if (is_array($session)) {
1629
$this->injector->session = & $session;
1730
}
18-
$this->injector->ssl_verification = $ssl_verification;
1931
}
2032

2133
/**
@@ -80,41 +92,75 @@ public function generateStateToken() {
8092
return $unique_token;
8193
}
8294

83-
public function auth($code) {
84-
if (!$this->initialized) {
85-
throw new NotInitializedException('You must initialize the OAuth instance.');
86-
}
87-
$request = $this->injector->getRequest();
88-
$response = $request->make_request(array(
89-
'method' => 'POST',
90-
'url' => $this->injector->config['oauthd_url'] . '/auth/access_token',
91-
'body' => http_build_query(array(
92-
'code' => $code,
93-
'key' => $this->injector->config['app_key'],
94-
'secret' => $this->injector->config['app_secret']
95-
)) ,
96-
'headers' => array(
97-
'Content-Type' => 'application/x-www-form-urlencoded'
98-
)
99-
));
100-
$result = $response->body;
101-
102-
if (isset($result->provider)) {
103-
$this->injector->session['oauthio']['auth'][$result->provider] = json_decode(json_encode($result) , true);
95+
public function refreshCredentials($credentials, $force = false) {
96+
$date = new \DateTime();
97+
$credentials['refreshed'] = false;
98+
if (isset($credentials['refresh_token']) && ((isset($credentials['expires']) && $date->getTimestamp() > $credentials['expires']) || $force)) {
99+
$request = $this->injector->getRequest();
100+
$response = $request->make_request(array(
101+
'method' => 'POST',
102+
'url' => $this->injector->config['oauthd_url'] . '/auth/refresh_token/' . $credentials['provider'],
103+
'body' => http_build_query(array(
104+
'token' => $credentials['refresh_token'],
105+
'key' => $this->injector->config['app_key'],
106+
'secret' => $this->injector->config['app_secret']
107+
)) ,
108+
'headers' => array(
109+
'Content-Type' => 'application/x-www-form-urlencoded'
110+
)
111+
));
112+
$refreshed = json_decode(json_encode($response->body) , true);
113+
114+
foreach ($refreshed as $k => $v) {
115+
$credentials[$k] = $v;
116+
}
117+
$credentials['refreshed'] = true;
118+
104119
}
105-
return json_decode(json_encode($result) , true);
120+
return $credentials;
106121
}
107-
108-
public function create($provider) {
122+
123+
public function auth($provider, $options = array()) {
124+
125+
// $options can contain code, credentials, or nothing. If nothing --> session call
109126
if (!$this->initialized) {
110127
throw new NotInitializedException('You must initialize the OAuth instance.');
111128
}
112-
if (isset($this->injector->session['oauthio']['auth'][$provider])) {
113-
$request = new Request();
114-
$request->initialize($provider);
115-
return $request;
129+
if (isset($options['code'])) {
130+
$request = $this->injector->getRequest();
131+
$response = $request->make_request(array(
132+
'method' => 'POST',
133+
'url' => $this->injector->config['oauthd_url'] . '/auth/access_token',
134+
'body' => http_build_query(array(
135+
'code' => $options['code'],
136+
'key' => $this->injector->config['app_key'],
137+
'secret' => $this->injector->config['app_secret']
138+
)) ,
139+
'headers' => array(
140+
'Content-Type' => 'application/x-www-form-urlencoded'
141+
)
142+
));
143+
$credentials = json_decode(json_encode($response->body) , true);
144+
if (isset($credentials['expires_in'])) {
145+
$date = new \DateTime();
146+
$credentials['expires'] = $date->getTimestamp() + $credentials['expires_in'];
147+
}
148+
149+
if (isset($credentials['provider'])) {
150+
$this->injector->session['oauthio']['auth'][$credentials['provider']] = $credentials;
151+
}
152+
} else if (isset($options['credentials'])) {
153+
$credentials = $options['credentials'];
116154
} else {
117-
throw new NotAuthenticatedException('The user is not authenticated for that provider');
155+
if (isset($this->injector->session['oauthio']['auth'][$provider])) {
156+
$credentials = $this->injector->session['oauthio']['auth'][$provider];
157+
} else {
158+
throw new NotAuthenticatedException('The user is not authenticated for that provider');
159+
}
118160
}
161+
$credentials = $this->refreshCredentials($credentials, isset($options['force_refresh']) ? $options['force_refresh'] : false);
162+
$request_object = new RequestObject($credentials);
163+
164+
return $request_object;
119165
}
120166
}

0 commit comments

Comments
 (0)