Auth0 Home Blog Docs

Email address missing in access token when using Google Cloud Endpoint?


#1

Hi,

I am trying to use the Auth0 service together with the Google Cloud Endpoint service. According to the Google Cloud Endpoint “Authenticating Users” documentation, in the “Receiving auth results in your API” section, given at:

https://cloud.google.com/endpoints/docs/openapi/authenticating-users

the Endpoint service should, depending on the “scope” used, “extract” some information from the Auth2 bearer token and forward the information as a JSON document looking like the following:

  {
    "issuer": TOKEN_ISSUER,
    "id": USER_ID,
    "email" : USER_EMAIL     
  }

(base64 encoded and added as a “X-Endpoint-API-UserInfo” HTTP header).

The “scope” is set to “openid profile email” in the client, but unfortunately I get only the “issuer” and “id” part, not the “email” part.

I was under the impression that if you listed “email” in the “scope” then the email address would be part of the “access token”, but this seems not to happen in this case. Could there be something that I have overlooked here or misunderstood?

Thanks in advance!

br,
kmm


#2

@kmm when you use the OpenID Connect scopes openid profile email that influences what auth0 will tuck into the id_token and/or will return those associated claims from the /userinfo endpoint when called with the access_token. The access_token itself won’t actually contain those claims, but should be capable of retrieving the claims associated with those scopes from that endpoint.

With the access token you get back from auth0 what happens when you call /userinfo endpoint. Does that endpoint return all of the scopes.

Can you share the code you use to authenticate your users and get a toke?


#3

@sgmeyer Thanks for your answer!

Yes, I noticed the presence of the id_token and its content. I assume that this means that you either have to:

  1. Use the /userinfo endpoint to obtain the information (as you indicates).

  2. Or maybe just forward the id_token together with the access_token to the backend and extract the information from there (after verification).

Anything that speaks against option 2, as you then don’t have to do an extra roundtrip to the network?

Btw., the code that I have been working with is basically the tutorial code from Google and from Auth0. Specifically:

https://github.com/GoogleCloudPlatform/python-docs-samples/tree/master/endpoints/getting-started

for the server side code. And for the client part I have been using the “Auth0 Vue” demo example as found at

https://auth0.com/docs/quickstart/spa/vuejs/01-login

(with updated the audience and scope settings in src/auth/AuthService.js).

Btw., I noticed that the id_token in my tests did not included the “kid” value in the header part of the token, and that the token therefore could not be verified. Is it possible to add the this “kid” value to the token, or du you have to use the “kid” value from the access_token?

br,
kmm


#4

@kmm I would highly recommend not sending an id_token to an API. This token is really meant for an application to consume as the aud claim in the JWT will be the client_id for which the user authenticated. The access_token will have sufficient scopes and audience for the /userinfo endpoint and can be used to send there.

In other words id_token is meant for the application and access_token is meant for an API.

Btw., I noticed that the id_token in my tests did not included the “kid” value in the header part of the token, and that the token therefore could not be verified. Is it possible to add the this “kid” value to the token, or du you have to use the “kid” value from the access_token?

The client’s advanced settings will contain how the id_token will be signed. Make sure that doesn’t say HS256. This signature type does not use JWKS endpoint and won’t use the kid value because the key necessary to verify the signature is not safe to put on a public endpoint. If you use RS256 then this uses an asymmetric algo to sign. Meaning we can host the public key on the JWKS endpoint. Can you confirm if this is the case:


#5

@sgmeyer Thanks for your answer!

(Sorry for being late responding.)

Checked and you’re right. The “advanced settings” menu showed that the id_token was signed using HS256 and not RS256. Updated and now the “kid” value is present in the header part.

Btw, about the adding email to the body part of the access_token. A colleage of mine noticed that you could use the “rules” feature and add a rule that looks something like the following:

function (user, context, callback) {
  const namespace = 'https://somewhere.eu.auth0.com/';
  context.accessToken[namespace + 'email'] = user.email;
  callback(null, user, context);
}

which would then result in that the key/value pair:

"https://<something>.eu.auth0.com/email": "someone@somewhere.com"

got inserted into the body part of the access_token.

But I am not sure if this is a feasible way of getting the email address added, as while the rule worked as indended when I tested this a few days ago, I seems to be unable to get it to work today. Not sure about what is going on?

br,
kmm


#6

@kmm great news! Also, as far as email address goes, this is the best way to add email to the access_token. The main thing here is make sure you namespace the claim using a URL namespace (as you’ve done in the example code above). Lastly, in order for the claim to show up in the access_token you must ensure you are passing in an audience when authenticating. This will ensure the access_token is a JWT.


#7

Note that this namespace will NOT work.

As stated in the doc:

auth0.com, webtask.io and webtask.run are Auth0 domains and therefore cannot be used as a namespace identifier.

Doc:


#9

Can someone explain why id_token is not recommended to be sent to an api server? It seems like an unnecessary extra step to have to create a rule with a namespace just to get information into the access_token that I can send to my api server that already exists in the id_token.

Thanks!