-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refresh_token is not avaliable in response #263
Comments
Are you calling $client->setAccessType("offline"); before you generate the auth url? That parameter needs to be passed at that point, not when exchanging. |
yes i am doing it before the generating the auth url. |
Could you put together a minimal code sample that demonstrates the problem? I can't reproduce it here at the moment. |
this is my code every thing is working fine for 1-2 hours but after that my token get expired and i am unable to refresh that as i mention previously. include_once('../../../functions/drives_connections.php'); $api_connections=new Api_Connections(); $client_id = $client_details["client_id"]; /************************************************ $client = new Google_Client(); if (isset($_REQUEST['logout'])) { if (isset($_GET['code'])) { $client->setApprovalPrompt("auto"); $_SESSION['upload_token'] = $client->getAccessToken(); } |
can you please provide a working example for the same in this repo with other examples ? |
I've found the only way to get this to work as you're intending is to set approval prompt to $client->setApprovalPrompt("force"); |
ok let me try $client->setApprovalPrompt("force"); this with my code. |
Ah, that explains it! Pugsley: you don't need force every time, only when you don't have a refresh token stored on the server. Basically, with Auto it will only show the consent dialog when the user has not previously given there consent. You will only get a refresh token if the consent dialog is shown. Therefore, when you get a refresh token it should be put into permenant storage like a database - you can look up the user using an api call from the access token or via ID token data. So, force causes the dialog to be shown every time, which means a refresh token every time, but that means you are churning refresh tokens, and you are giving the user a worse experience. Take a look at http://www.riskcompletefailure.com/2013/12/are-you-using-approvalpromptforce.html for a bit more on that. Clearly this is not very obvious, so what I'll do is add a note to the documentation highlighting this! navneetccna: to test this, try revoking your access, then signing in again. You can revoke through your account settings, or by getting an access token after you sign in and calling this URL: |
can you please provide a working example for the same in this repo with other examples ? |
As i try and change $client->setApprovalPrompt("auto"); to $client->setApprovalPrompt("force"); still didnt receive any refresh token in response {"access_token":"ya29.VwDJ4UGbKTKsyRwAAADusG-fltPrvhT_RtbHA5uiLLLU0pmXzerpqwkOSrv0CQ","token_type":"Bearer","expires_in":3598,"created":1407152019} can you please provide a working example for the same in this repo with other examples ? |
To confirm, did you see the consent screen once you changed it to force? |
nop |
Possibly it wasn't set before generating the auth URL then. Could you try revoking a (valid, not expired) access token, and then try again? |
yes i tried that too also i removed app from user account and tried this again |
I can confirm that after struggling with getting a refresh token, forcing the approval prompt and setting the access type to offline is sufficient to solve the issue. I did have to revoke the previous authorization to get this working as well. Something as such (I extended the Google_Client class for my implementation): Keep up the good work guys! |
I use the same code and for my application I need to autorize it twice. One time to get authorized for access, and another time to get offline access and retrieve refresh token. |
Both tokens come back at the same time - you'll get an access token for use immediately, and a refresh token for use in the future. Just request offline access and be aware that you only get a refresh token the first time (effectively, whenever the user sees a consent screen) - so you should store the refresh part against the user, and in future sign ins look it up. |
Actually I was confused by the message that is displayed when user authorize the application. The first time, nothing is displayed about offline access, but the refresh_token is well returned. If I call the authorize URL another time with forced promt, the message displayed show explicitly an offline access request (even if the access is already granted). |
That message is due to incremental auth. Take a look at http://www.riskcompletefailure.com/2013/12/are-you-using-approvalpromptforce.html for more on that. Re getting the token - nope, you're doing it the right way. It might be nice to have an accessor method on Google_Client though, feel free to send a PR or open an issue for that. |
I created PR #309 |
PR merged! |
@ianbarber, good article on why not to use Example: https://developers.google.com/apps-script/guides/rest/api
Above sample only saves the new access token (which doesn't contain the refresh token) and nowhere is explained that you'll need to save the refresh token separately, otherwise you'll lose it after the first time your access token is expired. The code sample basically works for the first two access tokens, then it'll stop working. Something like this would have been better:
This is probably a frequent cause of "Dang, why did it lose my refresh token? Again?!" |
Thank you for your comment. Yes, The authorize method checks if the refresh token exists. The developer just needs to make sure when they pass in an access token, it includes the refresh token. The sample you are linking to is referring to |
@erfanimani you sir are a gentleman and a scholar. That was the exact reason why it wasn't working. And I'm sure it's the reason why it wasn't working for @navneetccna either. Those code examples should be updated by Google. |
Google has updated their PHP quickstart, with an improved method to handle this: https://developers.google.com/apps-script/guides/rest/quickstart/php Snippet below: // Load previously authorized credentials from a file.
$credentialsPath = expandHomeDirectory(CREDENTIALS_PATH);
if (file_exists($credentialsPath)) {
$accessToken = json_decode(file_get_contents($credentialsPath), true);
} else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
printf("Open the following link in your browser:\n%s\n", $authUrl);
print 'Enter verification code: ';
$authCode = trim(fgets(STDIN));
// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
// Store the credentials to disk.
if(!file_exists(dirname($credentialsPath))) {
mkdir(dirname($credentialsPath), 0700, true);
}
file_put_contents($credentialsPath, json_encode($accessToken));
printf("Credentials saved to %s\n", $credentialsPath);
}
$client->setAccessToken($accessToken);
// Refresh the token if it's expired.
if ($client->isAccessTokenExpired()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
file_put_contents($credentialsPath, json_encode($client->getAccessToken()));
}
return $client; |
Hey guys, |
I am having this same error as previous users, even with the modified "refresh token". I even deleted my directory and started over and got the same error so I don't know what to do next. Can anyone give me guidance? Here's the error (and this is without making any modifications to the file quickstart.php): Fatal error: Uncaught LogicException: refresh token must be passed in or set as part of setAccessToken in C:\Users\mcgranj\Dropbox\eBay_web\google\vendor\google\apiclient\src\Google\Client.php:258 Stack trace: #0 C:\Users\mcgranj\Dropbox\eBay_web\google\quickstart.php(69): Google_Client->fetchAccessTokenWithRefreshToken(NULL) #1 C:\Users\mcgranj\Dropbox\eBay_web\google\quickstart.php(98): getClient() #2 {main} thrown in C:\Users\mcgranj\Dropbox\eBay_web\google\vendor\google\apiclient\src\Google\Client.php on line 258 |
@pugsley is right! In PHP SDK, adding
|
using following code to get token but there is no refresh token available in json
$client->setAccessType("offline");
$client->authenticate($_GET['code']);
$client->setApprovalPrompt("auto");
$_SESSION['upload_token'] = $client->getAccessToken();
print_r($_SESSION['upload_token']);
output :
{"access_token":"ya29.PgB0miRDMD3H-iAAAAD88eQLK9N84muCYYR4TEhwffsj5yNJBXMt34Sd6B815Q","token_type":"Bearer","expires_in":3597,"created":1404986763}
i am trying to refresh token for my app i want to show google drive list but after login and connect to the drive after some time token expired and unable to refresh the token
i want to save the token in database and use it for next time so user can access his google drive any time after connection it.
if i try following code
$client->refreshToken($google_token);
getting following error
Error refreshing the OAuth2 token, message: '{
"error" : "invalid_grant"
}'
The text was updated successfully, but these errors were encountered: