React-native-auth0 embedded social login not returning refresh token

I have a react-native project that uses an embedded login and react-native-auth0 (using expo AuthSession). I allow users to login with email/password, or social (facebook, google). I need the ability to store a refresh token on the device but I have only been successful in doing so with the email/password login with offline_access scope.

  1. Using passwordRealm with success:

     auth0.auth
     .passwordRealm({
         username: email,
         password: password,
         realm: connectionType,
         scope: 'offline_access openid profile',
         audience: AUTH_CONFIG.audience
     })
    
  2. Using /authorize (social) no refresh token:

authUrl: ${AUTH_CONFIG.domain}/authorize + toQueryString({
  connection: connectionType,
  client_id: AUTH_CONFIG.clientId,
  response_type: 'token',
  scope: 'offline_access openid profile',
  audience: AUTH_CONFIG.audience,
  redirect_uri: redirectUrl
})

This returns the access token and successfully authenticates the user, but no refresh token.

Any help with this would be appreciated!

1 Like

Hey there @mhopey,

The auth0 sdk provides an utility class in both IOS or Android SDK to store token security. You can take advantage of the interface. That following article explains that in details

https://auth0.com/docs/libraries/auth0-android/save-and-refresh-tokens#using-the-credentialsmanager-class

Alternatively, you can try the simplekeychain approach to store token.
https://auth0.com/docs/libraries/auth0-swift/save-and-refresh-jwt-tokens#alternative-method-simplekeychain

Please let me know if this helps answer your question. Thanks!

Hey @James.Morrison,

I should mention that I am using Expo for this project and the app has not been ejected. I was hoping to find a solution that would not require me to do so.

Here is the project that I was using for guidance:

https://github.com/expo/auth0-example

In my social login method I’m trying to use the /authorize endpoint and expo AuthSession

At https://auth0.com/docs/api/authentication#social it shows that I can include ADDITIONAL_PARAMETERS such as access_type=offline to retrieve a refresh token from the social provider. My attempts at doing so have been unsuccessful (using scope and appending ?access_type=offline to the request).

Please let me know if there are any other possible solutions you could direct me to.

Thanks for your help!

Are you seeing any specific error when you are working with access_type=offline? We don’t have samples written up for this specific use case with expo. I would like help, i just need more information. Thanks!

Here’s a sample response from the call to /authorize using &access_type=offline and expo AuthSession.startAsync(authUrl)

{
    "errorCode": undefined,
    "params":{
         "access_token":"eyXXX...",
         "exp://localhost:19000/--/expo-auth-session": "",
         "expires_in": "7200",
         "token_type": "Bearer",
    },
    "type":"success",
    "url":"exp://localhost:19000/--/expo-auth-session#access_token=eyXXX..."     

}

There is no error when I include access_type=offline as a request parameter, but “params” does not contain the refresh token.

After talking with our Support team it sounds like you are using a implicit grant which does not send refresh tokens.

Hi @mhopey.

The react-native-auth0 library implements the code authorization grant with PKCE , which is the appropriate flow for native applications. Your direct usage of the /authorize endpoint with response_type=token is triggering an “implicit flow” like @James.Morrison said, which is the flow used in SPA. The implicit flow, by definition, does not return refresh tokens because SPAs are not suited to keep a refresh token securely.

You can leverage react-native-auth0’s authorize method, which uses the code grant with PKCE. The recommended usage would display Auth0’s hosted login page (to let the user choose the desired login method) but if you are putting that option in your application, you can put the connection name directly in the authorize request like this:

auth0
    .webAuth
    .authorize({
      scope: 'openid email offline_access', 
      connection: the_connection_name,
      [...]
    })
    .then(credentials => console.log(credentials))
    .catch(error => console.log(error));
2 Likes

Hi @nicolas_sabena,

I’ve tried react-native-auth0’s authorize method exactly how you have it there. The error displayed is:
Missing NativeModule. Please make sure you run react-native link react-native-auth0

I am using Expo for this project and I’m looking for a solution that does not require me to eject the app to link libraries.

Not sure how Expo works and didn’t understand the “eject” bit, sorry about that.

Our libraries do indeed open the device’s native browser as per recommendations of the OAuth 2.0 Threat Model and Security Considerations. An embedded WebView is rejected by some identity providers (like Google) because it could potentially enable an application to steal the user credentials or do other malicious activities on behalf of the user (like automatically giving consent without the user intervention).

If you want to implement the flow in the app’s embedded browser (which, again, is not recommended because of security concerns and might be rejected by some identity providers) you will have to implement the Code Authorization grant with PKCE to obtain refresh tokens.

1 Like

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