I am building a web application using Laravel that uses a Google Account as a sign-in method. I've downloaded the Google+ PHP API from Github and wrote a singleton class for accessing the Google+ service. A snippet of this class is shown below:
// Returns a client ready to receive an access token.
private static function getClient() {
if (!self::$client) {
self::$client = new Google_Client();
self::$client->setApplicationName(self::$application_name);
self::$client->setClientId(self::$client_id);
self::$client->setClientSecret(self::$client_secret);
self::$client->setAccessType('offline');
// I'm only requesting the plus.login and userinfo.profile scopes.
self::$client->setScopes(self::$scopes);
// RedirectURI = 'postmessage'
self::$client->setRedirectUri(self::$redirect_uri);
}
return self::$client;
}
// Returns a client ready to be used for API calls.
private static function getClient2() {
$c = self::getClient();
// getToken returns the token session variable. This is the full
// JSON encoded token we got after authenticating the code.
$token = self::getToken();
$c->setAccessToken($token);
if ($c->isAccessTokenExpired()) {
// getRefreshToken returns the refresh_token session variable.
// This is a JSON decoded string that only contains
// the refresh_token value.
$refreshToken = self::getRefreshToken();
// This is the line that blows up.
$c->refreshToken($refreshToken);
// This code has never been reached :(
$newToken = $c->getAccessToken();
self::storeToken($newToken);
}
// If the access_token hasn't expired, we can merrily begin using
// the client to construct a Google_Service_Plus object.
return $c;
}
I am implementing the hybrid client/server flow. The first time a user signs on, a JavaScript callback is called which sends a code to be authenticated. The user is authenticated, the refresh_token
is stored in a database and in the current session, and I can successfully make API calls for the life of the access_token
.
After an hour, the access token expires. I test for this in getClient2()
and attempt to refresh the access_token
using the refresh_token
retrieved from the session (I have printed the session variables and can confirm they exist and are json_decoded). I then get the beautifully descriptive error
Error refreshing the OAuth2 token, message: 'invalid_grant'
At this point all pages depending on Google+ show an error page. The site becomes unresponsive unless the user returns to the site home page where JavaScript begins the sign-in flow again, allowing the server to obtain a valid access_token
for another hour.
I can post more of the singleton class if needed, but I think this is all that is relevant considering I am able to authenticate the user and make requests for the first hour.
Questions that are similar, but have not helped: