Google Refresh token not returning in user profile's identities section

Hi all

This is my use case:

  1. User signs in to my app via social login (google). The app is a SPA, using this code:
import { Auth0Client, User } from "@auth0/auth0-spa-js";

// init auth0 client
this.auth0 = new Auth0Client({
            domain: domain,
            client_id: clientId,
            audience: `https://${domain}/userinfo`,
            cacheLocation: "localstorage",
            useRefreshTokens: true,
            responseType: "id_token",
            scope: "openid profile email offline_access",
            connection: "google-oauth2",
            redirect_uri: `${window.location.origin}/home`,
            accessType: "offline",
            approvalPrompt: "consent",
            access_type: "offline",
            connection_scope:
                "https://www.googleapis.com/auth/calendar",
        });

...

// login which calls auth0 authorize endpoint
        await this.auth0.loginWithRedirect({
            redirect_uri: `${window.location.origin}/setup`,
            accessType: "offline",
            approvalPrompt: "consent",
            access_type: "offline",
            connection_scope:
                "https://www.googleapis.com/auth/calendar",
        });

  1. All scopes required for my app are requested (calendar, profile, email)
  2. Backend job tries to access google calendar API on behalf of user:
    a. Get user profile from Auth0
    b. Get the user’s google access/refresh token from user.identities[0]
    c. Refresh token if expired (using the user.identities[0].refresh_token from above
    d. Call Calendar API

However, when I get the user profile from mgmt API: /api/v2/users, I do not get the google refresh token, though documentation says otherwise. Only the access_token (which is short lived) is returned

How can I get Google refresh token returned from Auth0 user profile if my app is an SPA?

I have since changed the code to use PKCE flow, still does not work:

        this.auth0 = new Auth0Client({
            domain: domain,
            client_id: clientId,
            audience: `https://${domain}/userinfo`,
            cacheLocation: "localstorage",
            useRefreshTokens: true,
            responseType: "code",
            code_challenge_method: "S256",
            scope: "openid profile email offline_access",
            connection: "google-oauth2",
            redirect_uri: `${window.location.origin}/home`,
            approvalPrompt: "force",
            access_type: "offline",
            connection_scope: "https://www.googleapis.com/auth/calendar",
        });
// ... 

        const challenge = await this.getAuthChallenge();
        console.log({ challenge });
        await this.auth0.loginWithRedirect({
            redirect_uri: `${window.location.origin}`,
            approvalPrompt: "force",
            access_type: "offline",
            connection_scope: "https://www.googleapis.com/auth/calendar",
            code_challenge: challenge,
        });

Though Google does show “offline access” as requested:

image

Adding reply to bump this to the top

I just tested with the following snippets and it seemed to work (using auth0-spa-js 1.22):


auth0 = await createAuth0Client({
  domain: DOMAIN,
  client_id: CLIENT_ID,
  redirect_uri: URL,
  scope: 'openid email profile offline_access',
  audience: 'https://example.com'
})

await auth0.loginWithRedirect({
  access_type: 'offline',
  connection_scope: 'https://www.googleapis.com/auth/calendar',
  connection: 'google-oauth2'
})

The user should have both an access_token and arefresh_token in the identities array.

Also, make sure that the access token you call Management API (GET /api/v2/users) with has the read:user_idp_tokens scope. If not, it will return the identities array without those two attributes.

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