Hi Alex,
I’m trying to understand the correct way to secure my API using Auth0 and I found your post which seems somewhat similar to the issue I’m having (at least in terms of my understanding the flow). I’m building a chat application that makes requests against my Auth0-secured NodeJS-based API.
My users authenticate against Auth0 and get both an access token and an ID token. My app in Auth0 is set up as machine-to-machine (I’m not positive this is correct). The access tokens my users get look something like this:
{
iss: 'https://auth0_account_redacted.eu.auth0.com/',
sub: 'auth0|59f091cee40_my_ID_redacted',
aud: [
'https://my_domain_redacted.com/api',
'https://auth0_account_redacted.eu.auth0.com/userinfo'
],
iat: 1589809948,
exp: 1589896348,
azp: 'd8mQsZ7khKj313slB_app_ID_redacted',
scope: 'openid profile'
}
And the ID tokens looks like this:
{
'https://my_site_id/roles': [ 'admin' ],
'https://my_site_id/claimspermissions': [
'create:post',
'read:post',
'some:other',
'scopes:below'
],
'https://my_site_id/claimsgroups': [ 'admin' ],
'https://my_site_id/claimsroles': [ 'admin' ],
nickname: 'tom',
name: 'tom@my_email_domain.com',
picture: 'https://s.gravatar.com/blah.png',
updated_at: '2020-05-18T13:52:26.281Z',
iss: 'https://auth0_account_redacted.eu.auth0.com/',
sub: 'auth0|59f091cee40_my_ID_redacted',
aud: 'd8mQsZ7khKj313slB_app_ID_redacted',
iat: 1589809948,
exp: 1589845948
}
I then use the access token to call the Node API. The API validates the token and then either grants access to the resource (in this case, posting a message) or it doesn’t. This all works fine.
What I’m not understanding is how, if I use the access token and not the ID token, I get the username and be sure it’s what it should be (the username in the access token - the sub field - is the Auth0 database ID and not the actual username).
The answer seems to be that my API should call the Auth0 userinfo endpoint, passing it the access token, which will return the username and other info about the scopes allowed (and that does indeed work). But that means I’ll end up making three requests to Auth0: one to log the user in and get tokens in the first place, and then two more requests each time they access the API - once to validate the token, and then again to get the username. As you say, this seems like quite a lot of work, and if the app is very busy means I’m going to be making a lot of calls to Auth0 (unless I’m supposed to cache the userinfo in my app?). If I used the ID token, which I do seem to be able to verify, I could just take the username directly from it.
Perhaps I’m not understanding the process flow correctly, and I either have it right and it does require that extra step to get the username, or I’m expected to cache usernames somehow? I’d be grateful for any pointers.
Thanks very much.
Edit: I’m almost positive I’m simply not understanding how this is supposed to work. I’ve read lots of tutorials, but I don’t seem to be getting it.