8

Trying to wrap my head around using Laravel's Passport with mobile clients. The Password Grant type of authentication seems to be the way to go, and i have it working with my iOS app, however i can't get token refreshing to work.

When authenticating i get a token and a refresh token which i store, however when the token expires, calling the oauth/token/refresh route doesn't work. The route is using the web middleware which means my app using the api route can't access it. I'm not sure if they intended for mobile clients to never refresh or if they wanted you to roll your own refreshing? If anyone has insight on how this is supposed to work, that'd be great.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Chris
  • 1,750
  • 2
  • 14
  • 23

2 Answers2

17

The oauth/token/refresh route is not for refreshing access tokens. It is used to refresh transient tokens, which are used when you consume your own API from your javascript.

To use your refresh_token to refresh your access token, you need to call the oauth/token route with the grant_type of refresh_token.

This is the example provided by the documentation:

$http = new GuzzleHttp\Client;

$response = $http->post('http://your-app.com/oauth/token', [
    'form_params' => [
        'grant_type' => 'refresh_token',
        'refresh_token' => 'the-refresh-token',
        'client_id' => 'client-id',
        'client_secret' => 'client-secret',
        'scope' => '',
    ],
]);

return json_decode((string) $response->getBody(), true);

One note about scopes, when you refresh the token, you can only obtain identical or narrower scopes than the original access token. If you attempt to get a scope that was not provided by the original access token, you will get an error.

patricus
  • 59,488
  • 15
  • 143
  • 145
  • Wow, i don't know how that was escaping me, i guess i just assumed i would be calling a completely different route to refresh the token. Thanks! – Chris Aug 24 '17 at 19:19
  • Hey did you ever get this to work? I have the same issue and I have the settings exactly like how it is above. I've tried everything and its driving me crazy, this is the error message i get. League\OAuth2\Server\Exception\OAuthServerException: The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. – Daniel Park Aug 30 '17 at 04:01
  • 1
    If you could help me out with how you solved it that would be awesome. also are you storing the refresh token in a cookie or passing it straight from the browser? which is not recommended.. – Daniel Park Aug 30 '17 at 04:01
  • Ufff, this is not in Laravel passport documentation, I think I checked it and I didn't find it, thank you !! – José Lozano Hernández Oct 11 '19 at 20:02
5

I've done something like.

  1. Created an endpoint for grant refresh token.

and in my controller,

public function userRefreshToken(Request $request)
{
    $client = DB::table('oauth_clients')
        ->where('password_client', true)
        ->first();

    $data = [
        'grant_type' => 'refresh_token',
        'refresh_token' => $request->refresh_token,
        'client_id' => $client->id,
        'client_secret' => $client->secret,
        'scope' => ''
    ];
    $request = Request::create('/oauth/token', 'POST', $data);
    $content = json_decode(app()->handle($request)->getContent());

    return response()->json([
        'error' => false,
        'data' => [
            'meta' => [
                'token' => $content->access_token,
                'refresh_token' => $content->refresh_token,
                'type' => 'Bearer'
            ]
        ]
    ], Response::HTTP_OK);
}
Usama Munir
  • 589
  • 9
  • 11