Closed ghost closed 5 years ago
Nobody is interested in this project
It definitely somehow works both with access and refresh tokens, first one is temporary, the second one is used to obtain a new access token for all requests to API resources. Security thing.
I don't have time to understand all the workflow and how to use it fully with this lib. I think lib is able to take care of refreshing keys every hour, but we don't know how (documentation sucks).
Documentation says: use UserRefreshCredentials for initializing PhotosLibraryClient. And it really works with refresh token for every new album/photo/etc request, without using and without storing first obtained access_token, as in example project.
Two important things:
$oauth2->setCode($code);
$authToken = $oauth2->fetchAuthToken(); // this method obtains both tokens at first time
$refreshToken = $oauth2->getRefreshToken(); // not $authToken['access_token'];
$credentials = new UserRefreshCredentials(
$oauth2->getScope(),
[
'client_id' => $oauth2->getClientId(),
'client_secret' => $oauth2->getClientSecret(),
'refresh_token' => $refreshToken
]
);
// next, store $credentials somewhere and use for every PhotosLibraryClient initialization
// user will be prompted to grant access to selected scope
$authenticationUrl = $oauth2->buildFullAuthorizationUri(['access_type' => 'offline', 'prompt' => 'consent']);
Authentication is handled by the Google Auth Library for PHP.
You can find out more about the different types of tokens in the general OAuth documentation - and in particular in the Server-side Web Apps guide. The section on refreshing an access token explains that you can use a refresh token to generate a new access token once it has expired.
However, the Google Auth Library for PHP should handle a lot of these things for you. (Note that the refresh token is only returned at the first grant for your application. You'll need to store it or request it again using the 'prompt=consent' prompt as called out above in https://github.com/google/php-photoslibrary/issues/11#issuecomment-467665634 by @chaosaround .)
Hello,
I have the exact same problem than @munix. My token expires if I keep the code as it is in the existing example.
So I tried the solution @chaosaround shared but then I got an unsupported_grant_type
error.
My code is here (I only edited the $refreshToken
part and the prompt
option):
function connectWithGooglePhotos(array $scopes, $redirectURI)
{
$clientSecretJson = json_decode(
file_get_contents('../client_secret.json'),
true
)['web'];
$clientId = $clientSecretJson['client_id'];
$clientSecret = $clientSecretJson['client_secret'];
$oauth2 = new OAuth2([
'clientId' => $clientId,
'clientSecret' => $clientSecret,
'authorizationUri' => 'https://accounts.google.com/o/oauth2/v2/auth',
// Where to return the user to if they accept your request to access their account.
// You must authorize this URI in the Google API Console.
'redirectUri' => $redirectURI,
'tokenCredentialUri' => 'https://www.googleapis.com/oauth2/v4/token',
'scope' => $scopes,
]);
// The authorization URI will, upon redirecting, return a parameter called code.
if (!isset($_GET['code'])) {
$authenticationUrl = $oauth2->buildFullAuthorizationUri(['access_type' => 'offline', 'prompt' => 'consent']);
header("Location: " . $authenticationUrl);
} else {
// With the code returned by the OAuth flow, we can retrieve the refresh token.
$oauth2->setCode($_GET['code']);
// $authToken = $oauth2->fetchAuthToken();
// $refreshToken = $authToken['access_token'];
$refreshToken = $oauth2->getRefreshToken();
// The UserRefreshCredentials will use the refresh token to 'refresh' the credentials when they expire.
$_SESSION['credentials'] = new UserRefreshCredentials(
$scopes,
[
'client_id' => $clientId,
'client_secret' => $clientSecret,
'refresh_token' => $refreshToken
]
);
// Return the user to the home page.
header("Location: index.php");
}
}
I use the v1.4.0 of google/photos-library.
I searched about this issue but did not find anything helpful. Hopefully someone might help me with this.
In my application, replacing
$refreshToken = $authToken['access_token'];
with
$refreshToken = $authToken['refresh_token'];
fixed the issue.
However, user consent should be always required:
$authorizationUri = $oauth2->buildFullAuthorizationUri( [
'access_type' => 'offline',
'prompt' => 'consent',
] );
according to this stack overflow answer.
Although I use the parameter "access_type = offline" the token expires and I can not work offline for more than 1 hour. The error message is: { "error": "invalid_grant", "error_description": "Token has been expired or revoked." }
And the code is
$authCredentials = new UserRefreshCredentials( [ 'https://www.googleapis.com/auth/photoslibrary.sharing', 'https://www.googleapis.com/auth/photoslibrary' ], [ 'client_id' => $this->client_id, 'refresh_token' => $this->refreshToken, 'client_secret' => $this->clientSecret, ] );
How can I renew the token without user intervention?