Get User info from his access_token

Hello, I have this very same problem: Getting UserInfo using the Access Token - #3 by pulsemagic18 As you can notice there, there was no answer to the thread.

Basically, I am sending and validating the access token from the frontend to the backend (ReactJS - ExpressJS) correctly. But, take this scenario: If a user sends a post request and creates a new record on my database, I need to add a field identifying the user that created that record.

To achieve this, I need to get at least the user’s email (given his token). How can I accomplish that?

2 Likes

Hello @hugo.delacruz,

The user’s email address will be included in their idToken if you request the email scope. You can also add their email address to an access token using a rule, or you can query the /userinfo endpoint.

Hope that helps,
Mark

2 Likes

Thanks markd! This is what I get from the req.user object:

{ iss: ‘https://DOMAIN.auth0.com/’,
sub: ‘AXhOpnsWfvIa718SZ7dXC3uHPST8fE7p@clients’,
aud: ‘https://DOMAIN.auth0.com/api/v2/’,
iat: 1580246238,
exp: 1582838238,
azp: ‘AXhOpnsWfvIa718SZ7dXC3uHPST8fE7p’,
gty: ‘client-credentials’ }

I don’t know if I am looking at the right oject, but the access token itself is just a string, is there a way to parse/decode it to get the email?

Also, I am ery interested on knowing how te add the email scope or rule to get that info when my users log in with their Database email/password credentials or SSO credentials. Thanks!

In addition, calling /userinfo is not working for me, this code:

const auth0CallOptions = {
      url: 'https://DOMAIN.auth0.com/userinfo',
      auth: {
        bearer: req.headers.authorization.split(' ')[1],
      },
    };
    const auth0Callback = (error, response, body) => {
      if (!error) {
        console.log(body); // <==== Prints Unauthorized
      } else {
        console.log(error);
      }
    };

Results in a 401: Unauthorized

In your req.user example, looks like you have a token from a client credentials grant flow from your Auth0 Management API. That token is only good for talking to the Management API, while /userinfo is part of the Authentication API, which is why you are getting a 401 in your second example.

To talk to /userinfo you will want to log in using something like the authorization code flow instead, or maybe auth code + PKCE if you are dealing with a single-page app. Client Credentials is used in trusted machine-to-machine authentication scenarios, not for authenticating users.

Access tokens can be JWTs or opaque strings depending on the circumstances. Going on memory but I think client creds issues an opaque string.

Please excuse my ignorance. I’m no authentication expert.

I’m having the same issue and can’t find an example that shows how to send the correct token from @auth0/nextjs-auth0 library to the backend that contains the email address. I get the exact same token as Hugo.

What do I need to pass into this function to get the correct data?:

const { accessToken } = await getAccessToken(req, res, { 
    refresh: true,
    scopes: ['openid', 'profile', 'email']
  });

this code may be an issue as well:

export default handleAuth({
    async login(req, res) {

        const redirectUrl = getParameterByName('returnTo', req.headers.referer) || '/';
        try {
            await handleLogin(req, res, {
                authorizationParams: {
                audience: process.env.API_IDENTIFIER ,
                scope: 'openid profile email',
                grant_type: 'client_credentials'
                },
                returnTo: redirectUrl,
            });
        } catch (error: any) {
            res.status(error.status || 400).end(error.message);
        }
    },

Found a solution to how to include the user email in the access token!

You need to add a new rule in the auth pipeline on your Auth0 dashboard. They have a rule template specifically for including the user’s email in the access token. Once that is done your code should work.

You should test the contents of your JWT by entering it into https://jwt.io/ and seeing what the payload contains.

7 Likes

Thanks for sharing that with the rest of community!

1 Like