Reputation: 107
I'm integrating Gmail OAuth2 in Suite CRM. Everything is working fine on my local. I'm getting the refresh token on the first API call but on the production, I am getting the token/access token but getting an empty refresh token. Is this related to some Gmail permissions that are permitting my production application and allowing my local or something else?
Reference Code:
$params = [
'clientId' => $clientId,
'clientSecret' => $clientSecret,
'redirectUri' => $redirectUri,
'accessType' => 'offline',
];
$options = [];
session_start();
$provider = new Google($params);
$options = [
'scope' => [
'https://mail.google.com/'
]
];
if (null === $provider) {
exit('Provider missing');
}
if (!empty($_GET['error'])) {
// Got an error, probably user denied access
exit('Got error: ' . htmlspecialchars($_GET['error'], ENT_QUOTES, 'UTF-8'));
}
if (!isset($_GET['code'])) {
// If we don't have an authorization code then get one
$authUrl = $provider->getAuthorizationUrl($options);
$_SESSION['oauth2state'] = $provider->getState();
header('Location: ' . $authUrl);
exit;
// Check given state against previously stored one to mitigate CSRF attack
} elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) {
unset($_SESSION['oauth2state']);
unset($_SESSION['provider']);
exit('Invalid state');
} else {
// unset($_SESSION['provider']);
$token = $provider->getAccessToken(
'authorization_code',
[
'code' => $_GET['code']
]
); //Gets Token
$refresh_token = $token->getRefreshToken(); // Get Null in response
// Use this to interact with an API on the users behalf
$access_token = $token->getToken(); //access token
// Unix timestamp at which the access token expires
$access_tkn_expiration = $token->getExpires(); //access token expiry
Upvotes: 1
Views: 277
Reputation: 116968
With some languages mainly scripting languages which are web based, Google does not return a new refresh token every time. They assume that you have saved your refresh token.
To force a new one you can do a revoke on the users access token, which will cause the user to revoke your access of their data. Then the next time the user logs in they will be prompted to grant you access and you should get a new refresh token.
All this is assuming that you are requesting the offline
scope which i cant see from your code.
function getOauth2Client() {
try {
$client = buildClient();
// Set the refresh token on the client.
if (isset($_SESSION['refresh_token']) && $_SESSION['refresh_token']) {
$client->refreshToken($_SESSION['refresh_token']);
}
// If the user has already authorized this app then get an access token
// else redirect to ask the user to authorize access to Google Analytics.
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
// Set the access token on the client.
$client->setAccessToken($_SESSION['access_token']);
// Refresh the access token if it's expired.
if ($client->isAccessTokenExpired()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
$client->setAccessToken($client->getAccessToken());
$_SESSION['access_token'] = $client->getAccessToken();
}
return $client;
} else {
// We do not have access request access.
header('Location: ' . filter_var( $client->getRedirectUri(), FILTER_SANITIZE_URL));
}
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}
Upvotes: 1