Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scopes are unavailable in detailed response after initial login #823

Closed
Hawxy opened this issue Oct 19, 2021 · 4 comments · Fixed by #824
Closed

Scopes are unavailable in detailed response after initial login #823

Hawxy opened this issue Oct 19, 2021 · 4 comments · Fixed by #824
Labels
bug report This issue reports a suspect bug or issue with the SDK itself

Comments

@Hawxy
Copy link

Hawxy commented Oct 19, 2021

Describe the problem

I was previously using jwtdecode to spit out the scopes within my SPA, as I have a route guard that consumes them to check access to specific pages. I noticed that support for a detailed response was added, and thus decided to move over to it, however I'm running into a problem where the scopes are not returned immediately after login.

image

Scopes are present on the access token as expected, and are returned in the detailed response if I load the page after being already logged in.

Is this expected behavior?

Reproduction

Our auth service is a tad bespoke and was rewritten with Vue's Composition API in mind, a summarized extract with some annotations is below. Functionally it's fairly close to other Vue examples:

let client: Auth0Client

const state = reactive({
   loading: true,
   isAuthenticated: false,
   user: {} as User | undefined,
   error: null,
   scopes: [] as string[]
})

const getTokenSilently = async (o?: GetTokenSilentlyOptions) => {
   const result = await client.getTokenSilently({ ...o, detailedResponse: true });
   state.scopes = (result.scope as string).split(' ')
   return result.access_token;
}
// called via the `onMounted` hook within App.vue
const initializeAuth = async (options: Auth0ClientOptions) => {
   // removed logic that fetches org ID

   client = await createAuth0Client({
       redirect_uri: redirectUri,
       useRefreshTokens: true,
       organization: orgId,
       authorizeTimeoutInSeconds: 20,
       ...options
   })    
   try {
       if ((window.location.search.includes('code=') && window.location.search.includes('state='))
           || window.location.search.includes("error=")) {
           const { appState } = await client.handleRedirectCallback()

           router.push(appState?.targetUrl ?? window.location.pathname);
       }
   } catch (e) {
      // etc
   }
   state.isAuthenticated = await client.isAuthenticated()
   state.user = await client.getUser();
   // if we're signed in here, populate scopes
   if (state.isAuthenticated)
       await getTokenSilently();

   // setting loading to false permits the route guard to pass, falling through to the acl checks, thus scopes MUST be populated by this point
   state.loading = false

}

export const useAuth = () => {
   return {
       isAuthenticated: computed(() => state.isAuthenticated),
       loading: computed(() => state.loading),
       user: computed(() => state.user),
       scopes: computed(() => state.scopes),
       getIdTokenClaims,
       getTokenSilently,
       loginWithRedirect,
       logout,
       initializeAuth
   }
}

Environment

  • Version of auth0-spa-js used: 1.19.2
  • Which browsers have you tested in? Edge
  • Which framework are you using, if applicable (Angular, React, etc): Vue.js
@Hawxy Hawxy added the bug report This issue reports a suspect bug or issue with the SDK itself label Oct 19, 2021
@stevehobbsdev
Copy link
Contributor

Thanks @Hawxy. When requesting the detailed response, we should just be forwarding the scopes as returned from the token endpoint to you. Are you saying that scopes are present in the response from /oauth/token (if you inspect the network tab) but not present in the object we return from getTokenSilently?

@Hawxy
Copy link
Author

Hawxy commented Oct 19, 2021

Yes, that does appear to be the case.

@stevehobbsdev
Copy link
Contributor

Ok, let me have a look into it. I would not expect scopes to come back from the token endpoint unless they have changed from the initial auth request, as per section 5.1 in the OAuth2 spec. But if they are being returned and we're just not surfacing them in the detailed response, that's something to look into.

@stevehobbsdev
Copy link
Contributor

Ok I can see what's happening, getting the cached entry only takes into consideration the oauthTokenScope property for a detailed response but this property doesn't get written when redirecting back from auth.

There's a couple of ways we could solve this, will raise a PR 👍🏻

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug report This issue reports a suspect bug or issue with the SDK itself
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants