OAuth 2.0 access token has expired, and a refresh

2019-02-06 02:24发布

问题:

I have a web based application which use Google OAuth2.0 as the login framework. It works nicely previously until yesterday. The applcation couldn't get the refresh token after the access token expired. Besides that, the "Request for permission" page had change to "Have offline access" instead of "Know who you are on Google" and "View you email"

Originally, the "Request for permission" page will request the access to "Know who you are on Google" and "View you email". After user logout and attempts second login, the "Request for permission" page will be the same too.

However, until yesterday, the "Request for permission" page changed to "Have offline access". After the access token is expired, I got the error messsage below:

PHP Fatal error: Uncaught exception 'Google_AuthException' with message 'The OAuth 2.0 access token has expired, and a refresh token is not available. Refresh tokens are not returned for responses that were auto-approved.' in /home2/xxxx/public_html/test/google-api-php-client/src/auth/Google_OAuth2.php:221

I tried $client->setAccessType('online'); . However, I still got this fatal error with me. Below is my code to get the access token :

    if ($client->getAccessToken()) {
      $token = $client->getAccessToken();
      $authObj = json_decode($token);
      $refreshToken = $authObj->refresh_token;
      $user = $oauth2->userinfo->get();
      $me = $plus->people->get('me');
      $email = filter_var($user['email'], FILTER_SANITIZE_EMAIL); // get the USER EMAIL ADDRESS using OAuth2

      $optParams = array('maxResults' => 100);
      $activities = $plus->activities->listActivities('me', 'public', $optParams);


      $_SESSION['access_token'] = $client->getAccessToken();
    } else {
      $authUrl = $client->createAuthUrl();
    }

I tried to search for similar problem like me but I couldn't find one. This happened since yesterday. Before this, I never made any change on the codes.

回答1:

With his comments, Fabian Parzefall helped me getting this fixed.

Here's my script :

if($client->isAccessTokenExpired()) {

    $authUrl = $client->createAuthUrl();
    header('Location: ' . filter_var($authUrl, FILTER_SANITIZE_URL));

}

It's actually pretty simple. Instead of asking him to click the "connect me" button (as put by the demo script provided by the GA API team), I redirect him directly. Not sure if it's the proper/safer way, but that's the one working for me right now!



回答2:

  if($client->isAccessTokenExpired()) {

     $client->authenticate();
     $NewAccessToken = json_decode($client->getAccessToken());
     $client->refreshToken($NewAccessToken->refresh_token);

    }


回答3:

The answer above is 'correct' but I faffed around working out where to put it(!)... so post this for any one else trying out examples that end up with tokens expiring(!).

Once your code has done whatever token stuff it needs, and your client has an access token... then check it is still valid and if not send off for reauthorisation!

// Stuff to do with getting tokens and storing in session etc...

if ($client->getAccessToken()) { // Hey! we got one!
    if($client->isAccessTokenExpired()) { // Oh! its not good - go for another
        $authUrl = $client->createAuthUrl();
        header('Location: ' . filter_var($authUrl, FILTER_SANITIZE_URL));
        exit();
    }
  try{
...
     }