I have a GoogleDriveService to mange the work for the drive related.
Earlier it was setup by me to work like get the new refresh access token for each request and it was working fine.
Yesterday my senior suggested me to use this way:
1. To add the logic only get the new access token if it is expired.
2. I have added this logic but now I am getting 401 (Unauthorized) error.
My constructor code
public function __construct()
{
$client = new \Google\Client();
$client->setClientId(config('google.drive.client_id'));
$client->setClientSecret(config('google.drive.client_secret'));
$client->setRedirectUri(config('google.drive.redirect_uri'));
$client->addScope(\Google\Service\Drive::DRIVE);
$client->setAccessType('offline');
$client->setPrompt('consent');
// INFO: Get the oauth credentials as an array
$accessToken = OauthCredentials::first()->toArray();
// dd($accessToken);
Log::info('Db token', $accessToken);
if (!isset($accessToken['access_token'])) {
throw new \Exception('Failed to fetch access token. Check your refresh token!');
}
// INFO: Set the access token with all the details
$client->setAccessToken([
'access_token' => $accessToken['access_token'],
'refresh_token' => $accessToken['refresh_token'],
'token_type' => $accessToken['token_type'],
'expires_in' => (int) $accessToken['expires_in'],
'created' => (int) $accessToken['token_created_at'], // Unix timestamp
]);
// dump($client->isAccessTokenExpired());
/** Chech if the token is expired or not and refresh if needed */
if ($client->isAccessTokenExpired()) {
Log::info("Access token expired. Refreshing...");
// INFO: Use the db refresh token to fetch the new token
$newToken = $client->fetchAccessTokenWithRefreshToken($accessToken['refresh_token']);
// INFO: Set the refresh token if the new token doesn't have it
if (!isset($newToken['refresh_token'])) {
$newToken['refresh_token'] = $accessToken['refresh_token'];
}
/** Store the credentials and token related meta data to the db */
OauthCredentials::updateOrCreate(
['id' => 1],
[
'refresh_token' => $newToken['refresh_token'],
'access_token' => $newToken['access_token'],
'token_type' => $newToken['token_type'] ?? 'Bearer',
'expires_in' => $newToken['expires_in'],
'token_created_at' => $newToken['created'],
]
);
/** Store the credentials and token related meta data to the db */
Log::info('New token', $client->getAccessToken());
Log::info("New access token generated : ", $newToken);
// Set new token
$client->setAccessToken($newToken);
Log::info("New access token generated");
}
$this->drive = new \Google\Service\Drive($client);
$this->parentFolderId = config('google.drive.parent_folder_id');
}
As soon i removed this below line form the top (first) set access token
'created' => (int) $accessToken['token_created_at'], // Unix timestamp
It works but now each time it fetches the new access token for it.
Main error i am getting
"error": {
"code": 401,
"message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
"errors": [
{
"message": "Invalid Credentials",
"domain": "global",
"reason": "authError",
"location": "Authorization",
"locationType": "header"
}
],
"status": "UNAUTHENTICATED"
}
}