How can I make app_metadata available in /userinfo endpoint?

We have a very detailled level of authorization set-up for our API. Currently using the authorization-extension of auth0 to manage all of these authorizations. It can very well be that a single user receives up to 20 groups, 10 roles and 100 permissions. We need all of this information available in the API to do granular authorization. However, placing all of this information in the token could generate very large tokens, which the documentation also discourages. So, instead, we’ve turned the ‘Persistence’ switch on in the authorization-extension configuration

Now, after receiving an access token, when I do a call to https://example.eu.auth0.com/userinfo I would expect to get the app_metadata section in there as well. However this the actual response:

{"sub":"auth0|591xxx131a3","name":"sdegroot@mydomain","nickname":"sdegroot","picture":"https://s.gravatar.com/avatar/0b20cee90fb35eb54a6426808b89aa01?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fsd.png","updated_at":"2017-05-18T10:55:38.425Z"}

While I am using this as auth configurations for Lock:

auth: {
        redirectUrl: 'http://localhost:2000/auth0.html',
        responseType: 'token',
        sso: true,
        params: {
             audience: 'my-api-audience-name',
             scope: 'openid profile test:test groups permissions roles'
        }
}

The interesting thing, is in the documentation it mentions this:

You can also store the authorization
context information in the user
profile. The data will be stored in
the user’s app_metadata and you can
then use the Management API or the
/userinfo
endpoint to retrieve this
information after the user has logged
in.

However this doesn’t seem to work. How do you guys recommend me to proceed with this?

Thanks in advance!

1 Like

The documentation is incomplete as that was supported as part of the legacy flows, but now when using the new flows that adhere to the OpenID Connect specification (using API authorization implies the use of the new flows).

More specifically, the metadata is no longer returned in calls to the user information endpoint. See the comparison table at this documentation page.

For this scenario you can obtain the user metadata by going through the Management API instead.

1 Like

The documentation needs a lot of work. I burned hours yesterday trying to figure out how to get metadata returned in a token (auth0-js v8.8.0 on an SPA).

Is there a plan in place for bringing the documentation up to date so that users/customers don’t have to stumble around for hours in order to find documentation that’s correct?

3 Likes

On a related note, in order to access user and app metadata in an id token (I’m writing a SPA using auth-0 js v8.8.0), you’ll have to create a rule, first, such as the following:

function (user, context, callback) {
  const namespace = 'https://yourdomain.com/';
  context.idToken[namespace + 'user_metadata'] = user.user_metadata;
  context.idToken[namespace + 'app_metadata'] = user.app_metadata;
  callback(null, user, context);
}

Now, include user_metadata and app_metadata in your scope, and the fields will be included in the id token with the key names https://yourdomain.com/user_metadata and https://yourdomain.com/app_metadata, respectively.

I burned a couple of hours trying to figure this out yesterday due to auth0’s poor and in many cases out of date documentation, and the experience has made me somewhat skeptical of auth0’s solutions.

13 Likes

I have to agree with you that the documentation is inconsistent and often out of date. I am still struggling with getting user metadata and very confused about which method I should be using. Your answer helped, and that is the route I am taking so thank you!

I agree with @kurtmilam I’ve burned way too many hours on this simple issue. I still don’t know what the recommended solution is for accessing user_metadata through a SPA.

In the end, we decided to add the meta_data to the token using Rules.

function (user, context, callback) {
  context.accessToken"https://platform.caple.eu/partnerId"] = user.app_metadata.partner_id;
  context.accessToken"https://platform.caple.eu/country"] = user.app_metadata.country;
  context.accessToken"https://platform.caple.eu/roles"] = user.app_metadata.authorization.roles;
  
  callback(null, user, context);
}
3 Likes