Google-api-dotnet-client: Token is not showing expired

Created on 17 Jul 2018  Â·  23Comments  Â·  Source: googleapis/google-api-dotnet-client

I am using the standard clock, but I am in Japan (which means different time zone).
The permission has NOT been revoked and I can still see it on the permissions page : https://myaccount.google.com/u/1/permissions

cred.Issued is {7/17/2018 11:53:49 AM} about 30 minutes ago, expiredTimeInSeconds is 3600

image

With this bug it seems there is no way to revoke permission to the app.

p2 bug

All 23 comments

I think it might be expired because another access token request was made (the login) and that invalidated the stored access token. But shouldn't LoadTokenAsync be automatically refreshing an invalid access_token anyway by using the refresh_token?

@Worthy7 Thanks for reporting this issue, I've had a very quick look at the code and can't immediately see anything wrong. I'll look at reproducing this in the next day or two.

Just to clarify, I believe that these are the ways an access_token is invalidated:

  1. The user revokes permission via the permissions page
  2. The token simply expires
  3. The user logs in again
  4. The refresh token is used to manually refresh the access_token

Case 3 is the situation here. I had the user log in, which would invalidate the stored access token,but I was expecting LoadTokenAsync to detect that it was invalid (I guess this would require a call to google's servers?), but it seems it didn't, and so tried to use the invalid stored access_token to make the call to revoke.

What I am trying to achieve here is to remove the app permission when the user deletes their account.

Comment on 1: If a user revokes permission to the app the refresh token will not work anymore. Any access token that you have that has not expired will still continue to work.

Access tokens continue to work for their lifetime 1 hour. Even refreshing it will not prevent the first access token from continuing to work you will just have two valid access tokens.

Any off chance your code ran twice the first time it revoked the token the second time your getting an error that you cant revoke it because its invalid? Any chance you can give us a fill example of this happening? a small console application for example?

@Worthy7 Thanks for adding some clarification.

A call to flow.RevokeTokenAsync() deletes the users token from the local DataStore (code).
A call to flow.LoadTokenAsync() only loads the token from the local DataStore (code), returning null if the user does not have a token in the local DataStore.

To re-authorize a user who's token has been revoked, a full (re)-authorization is required, for example by calling GoogleWebAuthorizationBroker.ReauthorizeAsync(...).

If you are already doing this, or something similar, or if I've misunderstood the problem, please can you post a fuller example of your code so we can see more clearly what you're trying to do. Or, as Linda suggests, a self-contained console app that demonstrates the problem would be very useful.

@Worthy7 Just noticed that you're wanting to remove the app permission when the user deletes their account.
The way to do this is to call userCredential.RevokeTokenAsync(...), which programmatically revokes the app permission.
Note that as stated in the docs it can take some time before the revocation has full effect. Unfortunately "some time" doesn't seem to be defined anywhere so I don't know if that means a few seconds, minutes, days, or longer!

I know, it takes 5 seconds. It's very annoying.

On Thu, 19 Jul 2018, 19:19 Chris Bacon, notifications@github.com wrote:

@Worthy7 https://github.com/Worthy7 Just noticed that you're wanting to
remove the app permission when the user deletes their account.
The way to do this is to call userCredential.RevokeTokenAsync(...)
https://github.com/google/google-api-dotnet-client/blob/master/Src/Support/Google.Apis.Auth/OAuth2/UserCredential.cs#L153,
which programmatically revokes the app permission.
Note that as stated in the docs
https://developers.google.com/identity/protocols/OAuth2UserAgent#tokenrevoke
it can take some time before the revocation has full effect. Unfortunately
"some time" doesn't seem to be defined anywhere so I don't know if that
means a few seconds, minutes, days, or longer!

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/google/google-api-dotnet-client/issues/1256#issuecomment-406228742,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AEirHxT3uRMvL50hfLVObU08jatxlh2tks5uIF1CgaJpZM4VSIyz
.

as @Worthy7 stated in my experience its seconds and is probably related to the REST HTTP calls themselves taking some time.

It's actually Google's servers because if I delete, then log in again it
breaks because I don't get a refresh token unless I wait a few seconds
before trying. I guess it's difficult to avoid with such large scale infra

On Thu, 19 Jul 2018, 20:00 Linda Lawton, notifications@github.com wrote:

as @Worthy7 https://github.com/Worthy7 stated in my experience its
seconds and is probably related to the REST HTTP calls themselves taking
some time.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/google/google-api-dotnet-client/issues/1256#issuecomment-406238246,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AEirH-fF5jLuBoj6dSXeJtmlIKWgNjWzks5uIGa5gaJpZM4VSIyz
.

Yes, Google servers can take a while to propagate the revocation, beyond the time taken to actual perform the RPC. There is nothing we can do to change this.

@Worthy7 Is there still something that you think is wrong with the client library? Or has this conversation allowed you to achieve what you need to do?

Need more time to check. Give me a few days

@Worthy7 Sure, no problem :)

I can't reproduce this now, and I'd rather not backtrack to work it out. The error happened when my app was in an erroneous state with people who had no account, but did have their google credentials stored.
This code was running when a user tries to log in with google, we detect they have no account with us, then try to clear their credentials "just in case".

Difficult to explain but, FIN for now - thanks guys

Thanks for the explanation. If the error does re-occur, please feel free to comment here so we can re-open.

Hi there, just had this error again.
At what point does flow take care of auto-refreshing access tokens?

Switching to use the refresh token instead worked:

            if (accessToken == "")
            {
                accessToken = (await flow.LoadTokenAsync(providerKey, CancellationToken.None)).RefreshToken;
            }
            await flow.RevokeTokenAsync(providerKey, accessToken, CancellationToken.None);
        }

Reopened, but Chris is away this week so it'll be Monday before he's able to look again.

iir we refresh the token four minutes before it is due to expire

Where's the trigger to check and refresh?

On Fri, 3 Aug 2018 at 03:49, Linda Lawton notifications@github.com wrote:

iir we refresh the token four minutes before it is due to expire

—
You are receiving this because you modified the open/close state.
Reply to this email directly, view it on GitHub
https://github.com/google/google-api-dotnet-client/issues/1256#issuecomment-410030176,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AEirH-bvBulNKA6vRi9NdSOL9BKfmOXgks5uM0m-gaJpZM4VSIyz
.

The access-token is now refreshed at 6 minutes before it expires. See TokenResponse.cs.
The refreshing itself is managed by TokenRefreshManager.cs.
The check whether to refresh is in AuthorizationCodeWebApp.cs for web apps, or AuthorizationCodeInstalledApp.cs for installed apps.

So what is the trigger to check? Just initialization of flow?

I'm looking at the code and I can see that the only place ShouldRequestAuthorizationCode is called from is in AuthorizeAsync, but I can't see anywhere where AuthorizeAsync is called. When is it supposed to be called? (I just used Visual Studio to find references and it says just one in AutorizationCodeMvcApp but it's just an override.)

So am I supposed to be calling AuthorizeAsync myself at some point after initializing flow?

I think I am understanding it better now, I was not using the AuthorizationCodeWebApp class. I was just using flow directly instead.
I think this still means I need to manually call AuthorizeAsync on this class though to get the check to happen.
Anyway, I see the MVC example and it seems that is the case, so the checking of token is not automatic when requests are made, just during authorization of the user during initialization it seems.

Was this page helpful?
0 / 5 - 0 ratings