I have a single page application. I am able to get an access_token and id_token, but I do not get my user’s app_metadata in the decoded JWT.
My code is:
auth0 = new auth0.WebAuth({
domain: AUTH_CONFIG.domain,
clientID: AUTH_CONFIG.clientId,
redirectUri: AUTH_CONFIG.callbackUrl,
audience: AUTH_CONFIG.audience,
responseType: 'token id_token',
scope: 'openid email profile user_metadata app_metadata picture',
auto_login: false
})
The JWT for my id_token has the email, picture of the user - but not app_metadata inside it. What am I doing wrong?
I also noticed that the access_token scope only contains 3 items, openid email profile
, even though I requested 6.
2 Likes
You’re performing an OpenID Connect (OIDC) compliant authentication request which means the response will also comply to this specification. In particular, OIDC specifies what should be the outcome of presenting the openid
, email
and profile
scopes, but does not have any notion of the user_metadata
, app_metadata
or picture
values you also present as scopes.
Given there’s no notion of the above scopes the ID token will only contain the information associated with the standard scopes (see this section of the specification). If you want to include additional information as part of the ID token, then you’ll need to so with custom claims and also do it explicitly through the use of a rule (you can’t get metadata automatically just by including a certain scope value).
In addition, the /userinfo
endpoint response will also only honor the requested standard scopes and custom claims added. The returned access token, in some occasions can be used to call this endpoint so as such it will also reflect the standard scopes; the other scopes are not standard OIDC scopes and I guess that are also not defined within the API that is represented as AUTH_CONFIG.audience
so they are ignored.
Thanks @jmangelo for your kind response. Expanding a bit…
Developer options
Persistence
- Self-hosted database
- Backed by Auth0, specially the
app_metadata
and user_metadata
attributes from the Auth0 user profile.
Retrieval
- Self-hosted API
- Directly from Auth0
…
Implementation
We will consider hosting a database out of scope and constrain to Auth0-persistence.
Auth0 x Call from client
The Authentication API end-point userinfo endpoint does not support user_metadata
and app_metadata
retrieval directly.
Can either:
- Violate OICD conformance and include
user_metadata
, app_metadata
in the id_token
with a rule.
Will also need to uncheck compliance in the client (Client → Show Advanced Settings → OAuth)
![alt text][1]
- Have the client call the Auth0 Management API directly from the SPA (single page application). The appropriate Management API end-points are get_users_by_id and patch_users_by_id. As this is user clients hitting the management API, it is imperative to apply the principle least privilege! NB: For updating information there is a community supported widget, auth0-editprofile-widget, mentioned in Auth0 user profile details.
Auth0 x Self-hosted API
If you prefer to violate neither OICD conformance nor have user clients access the management API directly, there are options.
One is to create a thin API-proxy. The proxy takes user access_tokens
with a developer defined scope, e.g.read:user
. The backend, then uses the get_users_by_id to hit the Auth0 management API. Auth0 client credentials stay on the backend, within my control, instead of being available to the end-user client.
…
Auth0 feedback
Setting and retrieving user_metadata
is a common developer task. It shouldn’t be this difficult. I really don’t want to proxy request from end-user client → auth0, nor do I want end-user clients hitting the Auth0 management API directly. If I’ve missed something, pointing out a better solution would be awesome.
Otherwise, please add OICD conformant user info retrieval as a backlog item.
Just tossing out some ideas…
One option would be to simply allow user_metadata
and app_metadata
as query params on the Authentication API userinfo end-point using a similar query style as the Management API, i.e. fields=user_metadata&include_fields=true
.
Another option, would be a separate GET
/PUT
verb end-points (Authentication API) for accessing metadata.
For more of my thoughts on Auth0 as a vendor, see article on HackerNoon.
6 Likes