Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google api php client code not return refresh token

I have been trying to get refresh token from google api using javascript google client " code " that google return from client side. It returns me the code which i send to the server side. Now from server side i am sending the code to get the refresh token and access token using using google-api-php-client with this call :

https://www.googleapis.com/oauth2/v4/token

While i use the same code from google playground i get the response with refresh token as well but i do not get it from my own server.. This is the code

public function getRefreshToken($code)
{
    $client = new Google_Client();
    $client->setClientId(config('services.google.client_id'));
    $client->setClientSecret(config('services.google.client_secret'));
    $client->setRedirectUri('postmessage');
    $client->setScopes(config('services.google.scopes'));
    $client->setAccessType("offline");
    $client->setApprovalPrompt("force");
    dd($client->authenticate($code));
    dd($client->getRefreshToken());
    return ;
}

I have set access type to offline as mentioned in some answers but still i get the response with our refresh token.. this is the response

access_token :"xxxxxxxxxxxxxxxxxxxxxx"
created:1510242052
expires_in:3598
id_token:"xxxxxxxx"
token_type:"Bearer"
like image 428
Syed Abdur Rehman Kazmi Avatar asked Nov 09 '17 15:11

Syed Abdur Rehman Kazmi


1 Answers

Your php code looks fine to me. I suspect your front end javascript, specifically the link to google that it builds, may be to blame. Whether the authorization_code produces a refresh token when redeemed is partially dependent on what parameters are included in the initial link to Google.

As detailed in this answer, the javascript client library uses "client side flow". Normally in a front end app you'd specify response_type=token, but if you specify response_type=code, instead, you'll get a code back. But when redeemed, that code will not produce a refresh token.

For example, a link built by a front end javascript library might look like this:

https://accounts.google.com/o/oauth2/v2/auth?client_id=7xxxxxxxxxxx-xxxxxxxxxxx.apps.googleusercontent.com&redirect_uri=http://localhost:8080/oauth2callback.php&response_type=code&scope=profile

Your back end can redeem the code that comes back, but the response will not include a refresh token. This is by design.

One way to get a code that is eligible for refresh tokens, would be to use the back end PHP client library to build the link, rather than the javascript client library. $client->createAuthUrl() will build a link like this:

https://accounts.google.com/o/oauth2/auth?response_type=code&access_type=offline&client_id=7xxxxxxxxxx-hxxxxxxxxxxxxxxxx.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Foauth2callback.php&state&scope=profile&approval_prompt=force

This toy example builds the link this way and does receive refresh tokens.

Note the addition of access_type=offine and approval_prompt=force. After successful authentication, the redirect in this case includes a code that does provide a refresh token when redeemed.

The OAuth 2.0 playground builds an initial link that contains access_type=offline and prompt=consent, which also creates a code that is redeemable for a refresh token.

If this isn't helpful, perhaps you could update the question with the link to google that your front end is building? (With client id redacted, of course)

like image 167
Mike Patrick Avatar answered Sep 21 '22 15:09

Mike Patrick