Search code examples
google-apigoogle-oauthgoogle-analytics-apigoogle-api-php-clientgoogle-api-client

Google OAuth: can't get refresh token with authorization code


I am using Google API Client for Google Analytics with OAuth 2.0

I read this to get the refresh token but it doesn't appears: https://developers.google.com/identity/protocols/OAuth2WebServer#offline

I only get this instead:

{
 "access_token": "ya29.twHFi4LsiF-AITwzCpupMmie-fljyTIzD9lG8y_OYUdEGKSDL7vD8LPKIqdzRwvoQAWd",
 "token_type": "Bearer",
 "expires_in": 3599,
 "id_token": "very long string"
}

Here is the code:

Javascript (to get the Authorization Code): that works

gapi.analytics.ready(function() {

    gapi.analytics.auth.authorize({
        container: 'embed-api-auth-container',
        clientid: '257497260674-ji56vq885ohe9cdr1j6u0bcpr6hu7rde.apps.googleusercontent.com',
    });

    gapi.analytics.auth.on('success', function(response) {
        var code = response.code;
        $.ajax({
            url: "getTokensFromCode.php",
            method: "GET",
            data: {
                "code": code
            },
            success: function (tokens) {
                // I can't get refresh token here, only get "access_token" and "id_token"
                console.log(tokens);
            }
        });


    });

});

PHP (to exchange Authorization Code for tokens): that doesn't work

// I get the authorization code in Javascript
$code = $_GET['code'];
$redirectURI = "postmessage";

$client = new Google_Client();
$client->setClientId($clientID);
$client->setClientSecret($clientSecret);
$client->setRedirectUri($redirectURI);
$client->addScope(Google_Service_Analytics::ANALYTICS_READONLY);
$client->setAccessType('offline');
$client->setApprovalPrompt('force');
$client->authenticate($code);

$tokens = $client->getAccessToken();
echo $tokens;

I need the refresh token in Javascript, that's why I get the authorization code in Javascript and make an Ajax request to get the refresh token.


Solution

  • You will only get the refresh_token the very first time that a user grants access to your app. You'll need to store the refresh_token somewhere to be able to use it afterwards. You won't get a new refresh token the next time a user logs in to your app.

    FWIW: using a refresh token in a Javascript client doesn't make a lot of sense since a Javascript client can't store it in a safe (confidential) way. Since Javascript clients live in browsers and users are present in browsers, you can just redirect the browser to the authorization endpoint again and you'll get a new access token (which is also the purpose of a refresh token). The SSO session for the user at Google will make sure that the user doesn't need to login again and that the experience is seamless.