Need definitive mechanism for obtaining Google refresh tokens

I am building a react native app and I have google social connections enabled.

  • In my app I am using ‘react-native-auth0’ to authorise users
  • In my backend I need to have offline access to google for various google API integrations

In the native app I am authorising using:

  const scopes =
      'offline_access openid profile email  open:wss-connection';

        await authorize({
          scope: scopes,
          audience: 'https://mydomain/api',
          additionalParameters: {
            ['access_type']: 'offline',
            ['connection_scope']:
'https://www.googleapis.com/auth/user.birthday.read,https://www.googleapis.com/auth/contacts.readonly,https://www.googleapis.com/auth/profile.emails.read',
          },

With this i do receive both an access token and a refresh token on the native client.

On my backend I am using the Auth0 users api to get identity information:

https://${config.auth.AUTH_DOMAIN}/api/v2/users/${encodedUserId}

I need this call to return the user’s access and refresh tokens. I get the access token in the identifies array. It does NOT return the refresh token.

I CAN get the refresh token If I authorise (in the native app) using ['prompt']: 'consent', … ie

        await authorize({
          scope: scopes,
          audience: 'https://mydomain/api',
          additionalParameters: {
            ['access_type']: 'offline',
            ['prompt']: 'consent',  // <---- added this
            ['connection_scope']:
'https://www.googleapis.com/auth/user.birthday.read,https://www.googleapis.com/auth/contacts.readonly,https://www.googleapis.com/auth/profile.emails.read',
          },

… However this results in the user being prompted once with Google’s consent screen and then an additional consent screen from Auth0. Both screens ask for the exact same consents including offline access.

This is a very poor and confusing user experience Why can’t i get the refresh token without using this additional prompt? Do i need to configure something on the console? Or do I need to do something else here? This feels like a pretty common use case.

Note there are so many articles here re refresh tokens that I think it should by now be clear that your docs are not clear enough. Many seem out of date, and it feels like a moving target.

Hi @PWebb

Welcome to the Auth0 Community!

Have you tried to switch the ['prompt']: 'consent' to ['prompt']: 'none' in order to initiate silent authentication for your app? That way the user will not get prompted by Google with the extra consent screen.

Let me know if this solves your issue.

Kind Regards,
Nik

Hi Nik,

A few issues:

Issue 1: Prompt Screen for [‘prompt’]:[‘consent’]

I had a look at [‘prompt’]: ‘none’. It does remove the second consent screen but I don’t think it solves the key issue which is the ability to get the refresh token back to the Auth0 backend. I’ve also noticed that it will sometimes cause login problems ( getting errors in the logs about Failed silent Auth.

Also, when I use ['prompt']:['consent'] I’ve noticed that the second consent screen ( from my-auth0-tennant.au.auth0.com) is asking permission for my google cloud account ( not the logged in user) to access my auth0 account ( using the Tennant name).

Specifically it’s asking “my-auth-tennant is requesting access to your google-cloud-app” ( I’ve substituted my-auth-tenant and google-cloud-app for the real values). So it’s not really ideal. It feels perhaps like a misconfiguration my end but I can’t see it.
the client is setup as:

const auth0 = new Auth0({
  domain: “my-auth0-tennant.au.auth0.com",
  clientId: " … “
});

Obviously that needs to be fixed as a user won’t understand that either. Can you think of why it is doing this?

Issue 2 - Refresh tokens

I think I mostly understand this issue but I’ve added it for completeness.

  • I’ve just had a situation where the google refresh token actually expired which is possible for a number of reasons ( eg using 7 day expiring google test accounts).
  • I get hold of the refresh token by querying https://${config.auth.AUTH_DOMAIN}/api/v2/users/${encodedUserId} but it isn’t in the identities (it must have been there at some point as that’s how I got the refresh token that has since expired)
  • I’ve got the user to re-consent / login using [‘prompt’]: ‘consent’ but that does not seem to be updating the refresh token in the Auth0 users identity in all cases. Note that I think this might be down to the way I’m managing test/dev users. I just wanted to mention it.
  • I’ve done a bit more research and I think Google only issues the refresh token on the first login / per client unless [‘prompt’]: ‘consent’ is provided ( it forces a refresh token re-issue in most cases) or if we ask for more scopes.

Hi again @PWebb

Thanks for all the extra info and I am sorry about the delayed response.

For your first questions, since you need to make the calls to Google’s API in order to retrieve some information for your users, I believe that both consent forms would be required and I was not able to find any out-of-the-box solution regarding skipping either of them. Also, regarding the Failed Silent Auth error, that most probably is caused by your application attempting to authenticate the user and failing because they are still in the consent forms. In that case, I believe it is for the best to keep using ['prompt']:['consent'].

Regarding the consent screens, you can take a look at the following documentation:

These should help you regarding updating the consent form text to be more understandable and suitable for your application. However, if the consent form from Google is generated on their end, I would advise to check out their documentation on the matter.

For your second question, the users/user_id endpoint will not return information regarding the refresh tokens that the user has, I would advise you to use the user_id/refresh-tokens as seen in our documentation.
Also, as long as the user is re-authenticated or re-consents, the refresh token should be refreshed. Indeed, that might be affected due to your configuration/way you manage the users.

Hope the information above is helpful, if you have any other questions, let me know!

Kind Regards,
Nik

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.