-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Not refreshing access token automatically #2350
Comments
👋 The
|
Sure thing. Let me know if you need more details: The code for my OAuth2Client:
Here's the full error I get:
|
Followup: Oddly enough, if I deliberately do NOT include the access token in the oAuth2Client, the refresh appears to happen just fine. A bug? Got the idea from this stack exchange thread but the guy seems just as confused as I am.
But... sending only the refresh token and refreshing the access token with every single request seems contrary to the intended design? I could probably check the clock before each request and not send the access_token when I expect it is about to expire, but doesn't this defeat the purpose of the "automatic refresh"? "This library will automatically use a refresh token to obtain a new access token if it is about to expire." |
Is there a preferred workaround until this is fixed? |
Hey folks, we haven't had a chance to dig in and see what's happening here. I don't think anything interesting has changed in the auth stack recently, so it requires some sleuthing. |
Further update: I seem to only run into this issue using the google drive.files.create() function, and the |
@calculuschild From https://github.com/googleapis/google-auth-library-nodejs#oauth2
(emphasis mine) Looking at the code you pasted originally:
You provided |
We have the same issue here, we've been struggling for days. |
Having the same problem. Commenting out the access_token doesn't work as well. |
I'm trying to get the expiry_date and pass it with the tokens as someone suggested. But using PassportJS, I'm not getting that with the tokens. I'm trying to decode the AccessToken to get the expiry_date using some jwt libraries (e.g. jsonwebtokens) but its not working. Can someone point me in the right direction on how to achieve this? |
We are seeing this issue with
|
Apparently we are also having this issue here https://www.github.com/shriyamadan/youtube-dashboard |
In my case, refresh token is expired in 1 week, because my app is in testing status https://developers.google.com/identity/protocols/oauth2#expiration |
someone found a solution to this problem? |
@calculuschild could you please provide a snippet of the code you're writing that's failing to refresh? I just tested with the following example: const {google} = require('googleapis');
const people = google.people('v1');
/**
* To use OAuth2 authentication, we need access to a a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI. To get these credentials for your application, visit https://console.cloud.google.com/apis/credentials.
*/
const keyPath = path.join(__dirname, 'oauth2.keys.json');
let keys = {redirect_uris: ['']};
if (fs.existsSync(keyPath)) {
keys = require(keyPath).web;
}
/**
* Create a new OAuth2 client with the configured keys.
*/
const oauth2Client = new google.auth.OAuth2(
keys.client_id,
keys.client_secret,
keys.redirect_uris[0]
);
oauth2Client.on('tokens', (tokens) => {
console.info('token event:');
console.info(tokens);
});
oauth2Client.credentials = {
refresh_token
}
/**
* This is one of the many ways you can configure googleapis to use authentication credentials. In this method, we're setting a global reference for all APIs. Any other API you use here, like google.drive('v3'), will now use this auth client. You can also override the auth client at the service and method call levels.
*/
google.options({auth: oauth2Client});
async function runSample() {
// retrieve user profile
const res = await people.people.get({
resourceName: 'people/me',
personFields: 'emailAddresses'
});
console.log(res.data);
}
const scopes = [
'https://www.googleapis.com/auth/contacts.readonly',
'https://www.googleapis.com/auth/user.emails.read',
'profile'
];
setInterval(() => {
runSample().catch((err) => {
console.info(err);
process.exit(1);
});
}, 10000); |
@viniferrareze @kazuooooo @calculuschild if the issue is that your app is in Testing status, follow the steps to make the app production: Or, while testing you may need to perform a new login when testing, to get a new refresh token periodically. |
@calculuschild, I've attempted to recreate your steps here. I haven't been able to reproduce your issue. See my code below:
Once I get the access token and refresh token, I can call the sample again just fine:
A couple of points of friction I had which might be useful to this thread:
I'm going to be closing for now, but feel free to reopen if you keep running into issues! |
How does this solve the issue if you did not change anything from the code he wrote? |
If you are reading this thread b/c you are getting a 403 sporadically, it's likely not an access token issue, but a service policy issue you are running into. |
Thank you. Actually it is more of the API refusing to refresh if the token was binded to the oAuthClient. If i only send the refresh token it works fine. Exactly the scenario happening with the poster. I am not adding the expiry date so that might be the issue i am assuming. Calling the api with a refresh token suits my usecase as anyway my API calls are not as frequent as the token life but was also having same concerns as the poster. Very weird why this is not well documented with the package. |
@madaher-dev this stuff can be a little more complicated than we'd all like. If you'd help, can I trouble you to create a new github issue, with an example of the code that you're trying, and the results? |
Two GoogleAuth clientOptions you might benefit from:
|
I can verify that forceRefreshOnFailure fixed the issue oauth2Client.setCredentials({ |
I am on typescript and I cannot put the |
Try sending only the refresh token without the actual token. |
This one gives me |
I notice because my consent screen isn't yet verified, the token tend to expire unexpectedly sometimes. It's quiet unpredictable. With that said, here are some options to debug:
oauth2Client.setCredentials({
// remove this
//access_token: googleAccessToken,
refresh_token: googleRefreshToken
});
|
Environment details
googleapis
version: 59.0.0Steps to reproduce
I expect the API to automatically refresh the access token on the next API call after it expires, but I only get an "Invalid Client" error. I can successfully access the API and upload/download google drive files until the access token expires, so I know the tokens I received from the API on first signin are valid. I have that same refresh token assigned to the oauth2client immediately before any request. I can verify that they are set via console.log. Is there some missing step to get the API to "automatically refresh the access token" as it says in the documentation?
The text was updated successfully, but these errors were encountered: