I've looked through other posts and they're either unanswered (Stopped getting refresh token from google's API) or no longer correct it seems.
I am trying to get a new refresh token from the google api, I have access_type = 'offline' and approval_prompt = 'force' but the response I'm getting back does not contain a refresh token. The other posts I have looked through says that having those two parameters should return me a refresh token.
Any ideas?
EDIT: I was thinking perhaps I could revoke the auth and have the user re-auth to get a fresh refresh_token. Would this work/is there a better solution?
I think I figured it out, instead of using approval_prompt=force you can use:
{
...
access_type='offline',
prompt='select_account consent'
}
to force a new approval screen and get a new refresh token.
Related
I am trying to use GA4 API (with Google Python Client & Google Analytics Data Python Client) of Google with the Credentials authentication:
credentials = Credentials(
token=config['access_token'],
refresh_token=config['refresh_token'],
client_id=config['client_id'],
client_secret=config['client_secret'],
token_uri="https://accounts.google.com/o/oauth2/token",
scopes=['https://www.googleapis.com/auth/analytics.readonly']
)
This is working when my access token is not expired. However, this access token is expiring after 1 hour and I want to refresh it via following method:
credentials.refresh(google.auth.transport.requests.Request())
However, this code is returning "invalid_grant" error.
For that problem, I checked almost everything suggested (i.e. system clock/ntp, user permissions, etc.) however I couldn't fix the problem.
Also, I can't figure out about the refresh_token that I use is valid for Google Analytics 4 or not.
So, the questions are:
How can I able to solve this problem?
How can I assure that the refresh_token is valid for GA4?
If not valid, how can I refresh the refresh_token?
Is there any suggestion on the refresh of access_token, any other method or anything else?
Thanks
In my case, the solution was creating new OAuth client and generate a refresh_token for that account depend on the Google Analytics scope.
For that purpose, after I create the new client, I downloaded the client_secrets.json and run the Complete Example by Google and finally I am able to refresh the token.
I am currently using Refit and have been handling my auth stuff in an AuthenticationService where I set my Refit settings to have AuthorizationHeaderValueGetter use my AuthenticationService.GetAuthenticationToken() to get my access_token. The logic inside my GetAuthenticationToken() method checks the token expiration and will attempt to use the refresh_token to get a new access_token if it is expired. If all fails it will show the login screen of my app.
My test group has reported that they are asked to login frequently so I feel like there is something not working optimally in my design.
Am I doing too much in the AuthorizationHeaderValueGetter?
Should I be doing this in a DelegatingHandler where I can resubmit the api request after getting a new access_token?
I have background fetch stuff that happens in my app so I need to be able to have the refresh_token automatically get a new access_token during the background process.
Ok, so I stumbled upon my issue. The sequence that created this problem in the wild is:
app is backgrounded after user is logged in and using app normally
the access_token expires while in the background
background fetch runs getting a new access_token and refresh_token and doing normal work
user foregrounds the app
The problem was that the new token info was not persisted when the background fetch ran. So, when the user foregrounded the app my ResumeManager checked IsUserLoggedIn which used the old token info, so it would see an expired access_token and tried to use an already consumed refresh_token since it was used in the background fetch. This resulted in an invalid_grant and the login screen was displayed.
The good news is, easy fix and my logic is fine, also it appears doing all this in the AuthorizationHeaderValueGetter is not a problem.
Hopefully this info helps someone else even though it was more a careless mistake than anything else.
I am using Google Analytics API to fetch analytics data. I tried to authenticate it using following steps:
Created OAuth client ID in https://console.developers.google.com/ credentials section.
In consent screen I had set publishing status as testing
In OAuth 2.0 Playground I got the refresh token using above generated client id and client secret
Then I am using it to generate access token through it.
But after a few days, the refresh token expires although it is mentioned that the refresh token's validity is life long.
If your app is in testing mode then user tokens will expire in 7 days. Please find this explanations here: https://support.google.com/cloud/answer/10311615#zippy=%2Ctesting
I needed to send mails from a gmail account that I have access to, using nodemailer. It works for a couple of days before my refresh token is mysteriously revoked, even though the account belongs to me. A google search brought me here and I had been watching for a while hoping someone would help with a solution.
As you mentioned, this seems to happen with only test/unverified apps and I'm guessing google revokes tokens for such applications in your account after a few days. After much trials and errors, here is what I did.
NOTE: This is solution is only applicable to accounts you own, otherwise you must verify your app to access other people's accounts
Generate a new refresh token (existing one is most likely revoked) as described in this SO post
Go to the security tab of your google account dashboard
Under the Recent security activity section, you should see a security alert for your app.
Click on the context menu next to the notification and click DISMISS
At this point you'll be presented with a dialog of options where you indicate the level of trust you have for the app. I just went ahead and said I trusted the developer/app, obviously. And that's it! The refresh token should persist after this.
I could not find anything related anywhere else.
The other answer pointed me in the right direction but for me the option was located somewhere else: security > security checkup/security issues found > context menu next to your app > dismiss
This issue seems to be for unverified apps, Simply delete the token file from your project and rerun the project, it will create a new token.
My problem was when I've added access_token instead of refresh_token.
What I did:
Go to https://console.cloud.google.com/apis/credentials/consent and change from the testing status to published.
Delete the current token file.
Authorize the API again by signing into your gmail account. You will be sent to a warning screen. From there, you can choose to proceed.
When done you'll get a new token file
The solution is to delete your token.json file to force Google to find a new token.
I was able to get it to work WITHOUT a verified app. Perhaps the refresh() method will work once my app is verified. Not sure on that one.
I'm using Google Sign-In. A user comes to my site and logs in with gapi.auth2.getAuthInstance().signIn(), or they are already logged in and when the page loads (or reloads) we fetch the status. At this point I have an identity token good for an hour that I can validate on the server.
When a user leaves the browser sitting (say, overnight), this token expires. gapi.auth2.getAuthInstance().isSignedIn.get() returns true, but the token does not validate.
How can I log in a user and keep them logged in while their session is active (ie, browser hasn't been closed)? Or refresh the token? Anything more graceful than reloading the page...
Edit: The refresh token is not a correct answer; I don't want offline access (and don't want to ask for the permission). Google obviously thinks the user is still signed into my application; the user can reload the page and get a new token without providing credentials again. Surely there is some mechanism more graceful than a hidden iframe to get an updated token?
If the token is expired, you can call gapi.auth2.getAuthInstance().currentUser.get().reloadAuthResponse(). It returns a Promise.
I've raised an issue with Google over this because it's simply ridiculous they haven't documented this properly.
My comment here advises how I've accomplished refresh using the above.
FWIW, we've managed to (mostly) make it work via a listener approach. It appears that 'userChanged' callback is invoked ~5 minutes before the access token expires. That's enough for us to extract and update the access token without refreshing the page.
What does not quite work though is when computer comes back from sleep. This can be solved relatively easy by reloading the page on wake up.
You can accomplish this with listeners.
var auth2 = gapi.auth2.getAuthInstance();
// Listen for changes to current user.
// (called shortly before expiration)
auth2.currentUser.listen(function(user){
// use new user in your OpenID Connect flow
});
This will allow you to keep current credentials, as long as the browser remains active.
If the computer is put to sleep additional work must done to get current credentials.
if (auth2.isSignedIn.get() == true) {
auth2.signIn();
}
You can use Refresh Token to get offline access. As per the official reference
Access tokens have limited lifetimes. If your application needs access to a Google API beyond the lifetime of a single access token, it can obtain a refresh token. A refresh token allows your application to obtain new access tokens.
Basically you will get the refresh token the first time you ask for authentication. You need to save that token securely for future use. The access token (you mentioned as identity token) expires after an hour. After that you have to use the refresh token each time you want to get a new usable access token.
Depending on the client library you are using the syntax will differ. following is a sample for php client library.
// get access token from refresh token if access token expire
if($client->getAuth()->isAccessTokenExpired()) {
$client->refreshToken($securelyPreservedRefreshToken);
$newToken = $client->getAccessToken();
}
check this for details steps.
I'm doing oauth in echo sign and have come across following steps.
App makes a get request to echosign along with the return url.
ex: https://secure.echosign.com/public/oauth?redirect_uri=https://example.com/oauthDemo&
response_type=code&client_id=d4HQNPFIXFD255H&scope=user_login:self+agreement_send:account
Echosign, asks the user to login to echosign and on success it appends code to the return url and sends back.
Taking the code from the return url, another post call is made to get the access token using which , api calls can be further made.
POST call to /oauth/token
On this success, token-access has been generated successfully.
The things here is, how can i bypass the step where user will not have to login to echosign. Is there other easier way to get the access-token, seems like, code needs to be generated each time to get a new access-token.
I'm working on meteor, angularjs. Also i couldnt find any working examples on js, is there any ?
Please correct any of my steps.
I couldn't find a way to bypass the user to login but this needs to be done only once.
At this step you get the access token, refresh token and expiry time in seconds.
Check if your access token has expired and if so then use your refresh token to get a new access token. You can use the refresh token indefinitely until the EchoSign user manually revokes your application's token.
User your access token to make API calls.
PS: I don't know any working examples in JS.