Include email in JWT

Hi, I have an AWS Lambda function which I use for authentication & authorization, but I don’t know how to verify the identity of the user (the email for example). It would be EXTREMLY useful if I could get the user email from the JWT token.
PS: From the client side, I’m getting the Auth0 token with auth0.getTokenSilently();

Do I have any option for solving this? I really need to check the email of the user from the JWT, so I can be sure I can trust the request.

1 Like

Hi @johnykes,

I assume you refer to the access token, not ID token, otherwise please clarify?

You can add it via custom claim in a rule.

context.accessToken['https://any-namespace/email'] = user.email;

Note that this namespace url is necessary, but can be any url, doesn’t even have to exist; see documentation linked above for details.

In the ID token on the other hand, it’s automatically in there as email root claim, if you request for the email scope in the authorization request (default is usually: openid profile email)

Do I have any option for solving this? I really need to check the email of the user from the JWT, so I can be sure I can trust the request.

Note that you should also check that the email is verified (via email_verified claim), otherwise anybody could just signup with any random email address.
However, I don’t fully understand what you mean with “trust the request”. In which way trusting it? The access token is cryptographically signed by the authorization server / Auth0. How exactly do you verify the request in the Lambda function based on request info and JWT?

By trusting the request I mean knowing for sure who is the user/client. The email is unique, so it’s perfect for that. I’ll check the documentation and come back.

It was easy, I never played with the “rules” section before :)) cool stuff, thanks!
It seems it works, but it’s strange that I need to include the namespace…

I tried this:

function (user, context, callback) {
  // Add Email claim to the access_token
  context.accessToken.custom_email = user.email;
  // test
  context.accessToken['https://johnykes.com/email'] = user.email;
  
  return callback(null, user, context);
}

but the email is added only on the line with the namespace, the other one works only on debug/try mode.
Anyway, thank you very much! :slight_smile:

2 Likes

Glad it worked.

but It’s strange that I need to include the namespace…

Not that strange actually :slight_smile: Reason is to avoid OIDC conflicts.

From docs:

By default, Auth0 always enforces namespacing; any custom claims with non-namespaced identifiers will be silently excluded from tokens.

We do allow non-OIDC claims without a namespace for legacy tenants using a non-OIDC-conformant pipeline with the Legacy User Profile enabled, but we strongly recommend that legacy tenants migrate to an OIDC-conformant flow.

Thanks again for clarifications! :slight_smile:

1 Like

We’re here for you @johnykes!

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