Skip to content

Commit f0602af

Browse files
committed
Merge pull request #51 from bshaffer/hkdobrev-refresh-token
Add example usage of refresh token
2 parents 87c9253 + d058275 commit f0602af

File tree

7 files changed

+80
-7
lines changed

7 files changed

+80
-7
lines changed

src/OAuth2Demo/Client/Controllers/RequestToken.php

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public static function addRoutes($routing)
1010
{
1111
$routing->get('/client/request_token/authorization_code', array(new self(), 'requestTokenWithAuthCode'))->bind('request_token_with_authcode');
1212
$routing->get('/client/request_token/user_credentials', array(new self(), 'requestTokenWithUserCredentials'))->bind('request_token_with_usercredentials');
13+
$routing->get('/client/request_token/refresh_token', array(new self(), 'requestTokenWithRefreshToken'))->bind('request_token_with_refresh_token');
1314

1415
}
1516

@@ -24,13 +25,17 @@ public function requestTokenWithAuthCode(Application $app)
2425

2526
$code = $app['request']->get('code');
2627

28+
$redirect_uri_params = array_filter(array(
29+
'show_refresh_token' => $app['request']->get('show_refresh_token'),
30+
));
31+
2732
// exchange authorization code for access token
2833
$query = array(
2934
'grant_type' => 'authorization_code',
3035
'code' => $code,
3136
'client_id' => $config['client_id'],
3237
'client_secret' => $config['client_secret'],
33-
'redirect_uri' => $urlgen->generate('authorize_redirect', array(), true),
38+
'redirect_uri' => $urlgen->generate('authorize_redirect', $redirect_uri_params, true),
3439
);
3540

3641
// determine the token endpoint to call based on our config (do this somewhere else?)
@@ -43,7 +48,11 @@ public function requestTokenWithAuthCode(Application $app)
4348

4449
// if it is succesful, display the token in our app
4550
if (isset($json['access_token'])) {
46-
return $twig->render('client/show_access_token.twig', array('token' => $json['access_token']));
51+
if ($app['request']->get('show_refresh_token')) {
52+
return $twig->render('client/show_refresh_token.twig', array('response' => $json));
53+
}
54+
55+
return $twig->render('client/show_access_token.twig', array('response' => $json));
4756
}
4857

4958
return $twig->render('client/failed_token_request.twig', array('response' => $json ? $json : $response));
@@ -80,7 +89,40 @@ public function requestTokenWithUserCredentials(Application $app)
8089

8190
// if it is succesful, display the token in our app
8291
if (isset($json['access_token'])) {
83-
return $twig->render('client/show_access_token.twig', array('token' => $json['access_token']));
92+
return $twig->render('client/show_access_token.twig', array('response' => $json));
93+
}
94+
95+
return $twig->render('client/failed_token_request.twig', array('response' => $json ? $json : $response));
96+
}
97+
98+
public function requestTokenWithRefreshToken(Application $app)
99+
{
100+
$twig = $app['twig']; // used to render twig templates
101+
$config = $app['parameters']; // the configuration for the current oauth implementation
102+
$urlgen = $app['url_generator']; // generates URLs based on our routing
103+
$http = $app['http_client']; // simple class used to make http requests
104+
105+
$refreshToken = $app['request']->get('refresh_token');
106+
107+
// exchange user credentials for access token
108+
$query = array(
109+
'grant_type' => 'refresh_token',
110+
'client_id' => $config['client_id'],
111+
'client_secret' => $config['client_secret'],
112+
'refresh_token' => $refreshToken,
113+
);
114+
115+
// determine the token endpoint to call based on our config (do this somewhere else?)
116+
$grantRoute = $config['token_route'];
117+
$endpoint = 0 === strpos($grantRoute, 'http') ? $grantRoute : $urlgen->generate($grantRoute, array(), true);
118+
119+
// make the token request via http and decode the json response
120+
$response = $http->post($endpoint, null, $query, $config['http_options'])->send();
121+
$json = json_decode((string) $response->getBody(), true);
122+
123+
// if it is succesful, display the token in our app
124+
if (isset($json['access_token'])) {
125+
return $twig->render('client/show_access_token.twig', array('response' => $json));
84126
}
85127

86128
return $twig->render('client/failed_token_request.twig', array('response' => $json ? $json : $response));

src/OAuth2Demo/Server/Server.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use OAuth2\Storage\Pdo;
1010
use OAuth2\GrantType\AuthorizationCode;
1111
use OAuth2\GrantType\UserCredentials;
12+
use OAuth2\GrantType\RefreshToken;
1213

1314
class Server implements ControllerProviderInterface
1415
{
@@ -29,6 +30,9 @@ public function setup(Application $app)
2930
$grantTypes = array(
3031
'authorization_code' => new AuthorizationCode($storage),
3132
'user_credentials' => new UserCredentials($storage),
33+
'refresh_token' => new RefreshToken($storage, array(
34+
'always_issue_new_refresh_token' => true,
35+
)),
3236
);
3337

3438
// instantiate the oauth server
@@ -67,4 +71,4 @@ private function generateSqliteDb()
6771
{
6872
include_once(__DIR__.'/../../../data/rebuild_db.php');
6973
}
70-
}
74+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<p>
2+
The <code>Refresh Token</code> grant type is typically used in tandem with the <code>Authorization Code</code> grant type. Click the "Authorize" button to receive an authorization code:
3+
</p>
4+
<a class="button" href="{{ app.parameters.authorize_route|slice(0, 4) == 'http' ? app.parameters.authorize_route : url(app.parameters.authorize_route) }}?response_type=code&client_id={{app.parameters.client_id}}&redirect_uri={{ url('authorize_redirect', {show_refresh_token:1})|url_encode() }}&state={{session_id}}">Authorize</a>

views/client/index.twig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111
<li><a href="#authcode">Authorization Code</a></li>
1212
<li><a href="#implicit">Implicit</a></li>
1313
<li><a href="#usercred">User Credentials</a></li>
14+
<li><a href="#refresh">Refresh Token</a></li>
1415
</ul>
1516
<div class="simpleTabsContent">{% include 'client/grant_types/_authorization_code.twig' %}</div>
1617
<div class="simpleTabsContent">{% include 'client/grant_types/_implicit.twig' %}</div>
1718
<div class="simpleTabsContent">{% include 'client/grant_types/_user_credentials.twig' %}</div>
19+
<div class="simpleTabsContent">{% include 'client/grant_types/_refresh_token.twig' %}</div>
1820
</div>
1921
{% endblock %}

views/client/show_access_token.twig

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@
22

33
{% block content %}
44
<h3>Token Retrieved!</h3>
5-
<pre><code> Access Token: {{ token }} </code></pre>
5+
<pre><code> Access Token: {{ response.access_token }} </code></pre>
6+
7+
{% if response.expires_in %}
8+
<div class="help"><em>Expires in {{ response.expires_in }} seconds</em></div>
9+
{% endif %}
610

711
<p>
812
Now use this token to make a request to the OAuth2.0 Server's APIs:
913
</p>
1014

11-
<a class="button" href="{{ path('request_resource', { 'token': token }) }}">make a resource request</a>
15+
<a class="button" href="{{ path('request_resource', { 'token': response.access_token }) }}">make a resource request</a>
1216

1317
<div class="help"><em>This token can now be used multiple times to make API requests for this user.</em></div>
1418

views/client/show_authorization_code.twig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
Now exchange the Authorization Code for an <strong>Access Token</strong>:
1010
<p>
1111

12-
<a class="button" href="{{ path('request_token_with_authcode', { 'code': code }) }}">make a token request</a>
12+
<a class="button" href="{{ path('request_token_with_authcode', { 'code': code, show_refresh_token: app.request.get('show_refresh_token') }) }}">make a token request</a>
1313

1414
<div class="help"><em>usually this is done behind the scenes, but we're going step-by-step so you don't miss anything!</em></div>
1515

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{% extends "client/base.twig" %}
2+
3+
{% block content %}
4+
<h3>Token Retrieved!</h3>
5+
6+
<p>
7+
But let's pretend this access token has expired. Luckily, it came with a refresh token!
8+
</p>
9+
10+
<pre><code> Refresh Token: {{ response.refresh_token }} </code></pre>
11+
12+
<a class="button" href="{{ path('request_token_with_refresh_token', { 'refresh_token': response.refresh_token }) }}">renew your access token</a>
13+
14+
<div class="help"><em>The refresh token can be used to get a new access token after the access token has expired.</em></div>
15+
16+
<a href="{{ path('homepage') }}">back</a>
17+
{% endblock %}

0 commit comments

Comments
 (0)