Get User Data Server Side - what is a good approach?

First of all: thanks for Auth0! I’m new to it and using it has been fantastic.

I presently puzzling together what the best way to plug Auth0 into my new application should be. I’ve been busily reading the docs for some time and I think I have an idea of how things are supposed to hang together. I wanted to express them here in the hope that you could say “yup, that’s the way to do it” or “no, no, no, STOP!”

Here’s my setup:

  • Client app is a React SPA which will use Lock to obtain an access token from Auth0.

  • It will talk to an ASP.NET Core application to obtain data, customised for the authenticated user using the access token.

What this means is, I need to be able to identify a user from an access_token. I’ve learned from reading the docs that passing an id_token is not the done thing. So that’s cool. The question is: how do I identify which user I have from the access_token?

I understand from the docs that it’s possible to take an AccessToken and get profile data by making a call to Auth0 and passing the token along; like so:

        var domain = _config"Auth0:Domain"];
        var apiClient = new AuthenticationApiClient(domain);
        var userInfo = await apiClient.GetUserInfoAsync(accessToken);

Now that’s great; but naturally I don’t want to call Auth0 on each API call. Looking at the Claims my ASP.NET Core app receives when the access token is passed I can see that we get a sub claim (also called http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier ). This includes a value that looks like this: auth0|1234567890andon. Questions that arise:

  1. Does sub uniquely identify a user? My guess is “yes”. (This seems to suggest that is so: Scopes )
  2. Is sub a reliable way of identifying a user in the long term? Does a user have a single sub which is assigned to their email address? Again, my guess is “yes”.
  3. Does that sub remain the same forever? Can a user’s sub ever change? I’m hoping the answer is “the sub remains the same forever”. My assumption would be that if I’m auth0|1234567890andon now then I’m auth0|1234567890andon always. Is that so?

Assuming the answers above are as hoped, I would think that specific user data could be uniquely keyed against the sub property in my database. If my app needs more information about a sub then it could use the access token (which sits alongside the sub in my claims) to call the apiClient.GetUserInfoAsync(accessToken).

Further, if I decide that I want to use a different user id in my database, as long as I maintain a table that maps sub to my own user id, I guess I’m good to go?

Does this all seem reasonable? Thanks again!

To see my approach in practice see this repo: GitHub - johnnyreilly/auth0-react-typescript-asp-net-core: A boilerplate illustrating Auth0 usage with a React / TypeScript client and an ASP.Net Server

I blogged about it here: Auth0, TypeScript and ASP.NET Core | johnnyreilly

Happy to correct any mistakes so I don’t spread bad information.

This was a similar question which I found useful:
http://community.auth0.com/questions/6761/get-user-data-server-side?childToView=6795#answer-6795

If it would help I’m happy to provide a repo that illustrates my approach as is. Let me know if that would help.

FWIW I’m planning to blog about this and will plan to share the approach as a TypeScript / ASP.NET Core boilerplate.

Thank you so much for the nice comments! (and for the beautifully written question)

Client app is a React SPA which will use Lock to obtain an access token from Auth0.

The recommended approach for SPAs is to use the implicit grant flow that redirects your users to the Hosted Login Page, instead of using Embedded (or self hosted) Lock, which is the version that you install from npm or that you get from our CDN directly in your app. We are working on our Custom Domains functionality, which will let you use your own domain to show the Hosted Login page instead of https://your_domain.auth0.com. This is available today for paying accounts in development mode and the version ready for paying accounts in production will be released in Q1 2018.

I understand from the docs that it’s possible to take an AccessToken and get profile data by making a call to Auth0 and passing the token along

This is an implementation that is particular to Auth0. If your access_token has a https://YOUR_DOMAIN.auth0.com/userinfo audience (which requires it to be an RS256 signed token), then you can call the userinfo endpoint of our Authentication API to get information about the user’s profile.

The sub claim:

In this case, the sub claim of the access_token is the user_id of the user that obtained that token. If you were using a non interactive flow like client credentials (which is used for machine to machine authentication), it would be the client_id and it would have a <client_id>@clients format.

The user_id is used to uniquely identify a user, as explained in this document. If you are using a custom DB, then you need to ensure that the user_id remains unique. it is a reliable way of identifying a user and it can’t be changed through the Management API (as can be seen in the list there, it’s not one of the attributes that can be updated). However, if you link accounts then one user_id will be considered the primary one, and the other one would be secondary so you’d have to handle this case separately.

Further, if I decide that I want to use a different user id in my database, as long as I maintain a table that maps sub to my own user id, I guess I’m good to go?

If you have a custom DB scenario, then you can use your own database as an identity provider in Auth0 to authenticate your users directly and keep the user_id you already have. You can also migrate your users from your Custom DB to Auth0.

Blog post:

Your blog post is great! Thank you very much for the kind comments there. I would only add a couple more details about the fact that, currently, any user on any client can ask for any scope defined in the Scopes section of your API and that you need to use a rule to implement access policies if you have certain scopes that can only be accessed by certain users, for example.

1 Like