Auth0 Home Blog Docs

How to get the Google OAuth2 refresh token?


#1

I’m using the AuthenticationApiClient C# lib to craft a Lock login for a Google account:

var client = new AuthenticationApiClient(new Uri($"https://{_configuration["Authentication:Auth0:Domain"]}"));
            var urlb = client.BuildAuthorizationUrl();
            var uri = urlb.WithClient(_configuration["Authentication:Auth0:ClientId"])
                .WithRedirectUrl(GetBaseUri() + "Organization/AuthorizeGAFinish?id=" + id + "&returnAction=" + returnAction)
                .WithResponseMode(AuthorizationResponseMode.FormPost)
                .WithResponseType(new AuthorizationResponseType[] { AuthorizationResponseType.IdToken, AuthorizationResponseType.Code, AuthorizationResponseType.Token })
                .WithNonce("1234")   
                .WithAudience(_configuration["Authentication:Auth0:Audience"])
                //.WithConnection("google-oauth2")
                .WithScope($"openid {Uri.EscapeUriString("https://www.googleapis.com/auth/analytics.readonly")}")
                //.WithValue("access_type","offline")
                .Build();

Later on I get the access token with:
var mgmtToken = await GenerateManagementApiToken();
var client = new ManagementApiClient(mgmtToken, new Uri(_configuration[“Authentication:Auth0:Audience”]));

            var auth0User = await client.Users.GetAsync(userId);
            return auth0User.Identities[0].AccessToken;

However I need the refresh token as I need to do this offline. However Identities[0].RefreshToken is always null.

I have tried forcing Lock to provide access_type=offline to Google by modifying the Auth0 hosted page with:
var authParams = config.internalOptions;
authParams.access_type = ‘offline’;
authParams.approval_prompt = ‘force’;

var lock = new Auth0Lock(config.clientID, config.auth0Domain, {
auth: {
redirectUrl: config.callbackURL,
responseType: (config.internalOptions || {}).response_type ||
(config.callbackOnLocationHash ? ‘token’ : ‘code’),
params: authParams
//params: config.internalOptions
},

Still doesn’t work. How do I get Auth0 to store the refresh token?


#2

:wave: @strich we could you use a Rule to store the Google Refresh Token, as explained here:

Google will only send you the refresh_token once, so if you haven’t stored it you may need to ask for it again as you mentioned using approval_prompt=force to explicitly consent again.

In addition, we can check to make sure we have added out developer keys for Google when setting up the connection un our Dashboard > Connections > Social


#3

Hi @kim.noel,

I can try that. But it is in direct contradiction with your documentation here: https://auth0.com/docs/tokens/idp#renew-the-token

IdP Refresh Tokens can be obtained the same way as Access Tokens, using the /api/v2/user/{user-id} endpoint. The Refresh Token will be available in the identities array, under the element for the particular connection.

Is this wrong, outdated?


#4

@kim.noel I tried setting up the rule (From the template) and I can see no additional metadata being created. It seems to be that Lock is not correctly passing the offline_access param to Google. Google is never showing ‘offline access’ as a permission type.


#5

calling that endpoint should indeed work. We had a similar issue with the Google refresh token here where the parameters were being passed successfully to Auth0, but not to Google. That thread may be helpful for you if you wanted to give it a glance. In that situation they needed to include connection_scope as well as scope for it to work. I am going to try reproducing the issue with your code. I will need some time to test this out.