Accesing metadata

Hi @fullmetalpinky,

I’ll try to answer all of these, although, no need to name anyone after me :laughing:.

1-2:
The first couple of questions are related to Actions. When advising on how to customize the login flow, we are now suggesting Actions instead of Rules, because it is likely that Rules will eventually be replaced by Actions.

To sum that up, Actions are the new, improved way to customize login flows.

There are a few different triggers for Actions. You can do stuff when someone signs up or changes their password, etc. The Login flow runs at the same point in the login flow that Rules run, so whatever you would write a rule for, you should use a post-login Action.

Actions are edited directly in your Auth0 dashboard:

  1. Go to Actions > Flows and select the
  2. Click Create Action on the right side to create a new Action
  3. Add code:

  1. Click “Add to flow” after you hit deploy. The link to add it to a flow will pop up on the top right:

When you create a new post-login Action, you will see the function called exports.onExecutePostLogin. Exports are used in Node.js to make code available throughout the app, but you don’t need to alter this at all from the default code. As you can see in the screenshot above, this is already written out for you. This is just how Auth0 will know about your custom code and at which point during login the run it.

3-4:
Slack is a messaging app that is often used in the workplace. It’s not related to Auth0, it’s just a common app and is used as an example for those who happen to already use Slack. This example is helpful because it shows you how you can make an API request in an Action and use Action features like storing secrets (sensitive info you want to keep hidden). A simpler example would be to go through the steps I added above and add a custom claim to the ID Token:

exports.onExecutePostLogin = async (event, api) => {
  const namespace = 'https://my-app.example.com';
  api.idToken.setCustomClaim(`${namespace}/groups`, "Some Group");
}

5. Nope, no need to learn cURL. cURL is a command-line/terminal tool to help you make HTTP requests. You can use postman or just make the requests in your code if you prefer.

6. Backend languages are provided because you can only use the Management API to assign roles from the backend. Alternatively, instead of using the Management API, you can assign roles from you dashboard UI:

Most things you’d use the Management API for you can do from the dashboard. If you need to do something programmatically/automated, then you’d want to use the Management API from your own backend or from within an Action. You’d have to create and authorize a machine-to-machine app to do that.

7. No need to use axios. You can use Angular2’s nattive HTTP module.

8. Yes, that’s correct! The ID Token is a JWT that contains profile info. You can extend the default claims and include your own custom claims from within a post-login Action.

9. There’s actually a shortcut for this in post-login Actions. You can update the user’s metadata from inside an action like this: api.user.setAppMetadata(name, value)

If you’d like to add app metadata and add it to the ID token, you do something like this in the Action:

exports.onExecutePostLogin = async (event, api) => {
  const groupName = "My Group"
  // Add the group to the user's metadata to permanently update the user
  api.user.setAppMetadata("group", groupName)

  // Add the group to the ID Token so that the app can see what group the user belongs to
  const namespace = 'https://my-app.example.com';
  api.idToken.setCustomClaim(`${namespace}/groups`, groupName);
}

OR You could also check to see if the user already has a group before updating it like this:

exports.onExecutePostLogin = async (event, api) => {
  const namespace = 'https://my-app.example.com';
  const userGroup = (event.user.app_metadata || {}).group;
  if (userGroup) {
    // Since the user already has a group, just add it to the ID Token
    api.idToken.setCustomClaim(`${namespace}/groups`, userGroup);
  } else {
    // Since the user does not have a group yet, we'll need to update the user's metadata AND add it to the ID Token
    const groupName = "My Group"
    // Add the group to the user's metadata to permanently update the user
    api.user.setAppMetadata("group", groupName)

    // Add the group to the ID Token so that the app can see what group the user belongs to
    api.idToken.setCustomClaim(`${namespace}/groups`, groupName);
  }
}

10. If you just need to update the user’s metadata, it will be much simpler to use a post-login Action. Otherwise, you will need to create a machine-to-machine app and authorize it to use the Management API and build a backend API for your Angular app. It is possible to do a few things with the Management API from the frontend (docs), but generally not recommended.

11. Flow here refers to what type of OAuth2 flow your app needs to use. For instance, a SPA uses Authorization Code flow with PKCE whereas a backend API might use Client Credentials flow. The docs here explain this in more detail: Which OAuth 2.0 Flow Should I Use?

12. The Management API is basically the API version of the Auth0 dashboard. For example, instead of creating a user by clicking the purple “+ Create User” button:

You can use the Management API’s POST/api/v2/users endpoint instead.

Pretty much everything you can do from the Auth0 dashboard, you can do programmatically with the Management API. As you can imagine, there are security concerns with such a powerful API, which is why you can only use this tool from the backend such as in an Action or in your own custom API.

13. In JavaScript, bracket notation (user["name"]) is another way to access a property in an object. This is used when you have special characters in the property key and cannot use dot notation user.name.

For example, user["name"] is the same as user.name. In this case, you could write it either way.
However, in the example, the property key is "https://my-app.example.com/groups”, and so I can’t use dot notation (user.https://my-app.example.com/groups is not valid), and so I can access the property like this instead (user["https://my-app.example.com/groups"]).

The full user object will look something like this:

{
  "iss": "http://my-domain.auth0.com",
  "sub": "auth0|123456",
  "aud": "my_client_id",
  "exp": 1311281970,
  "iat": 1311280970,
  "name": "Jane Doe",
  "given_name": "Jane",
  "family_name": "Doe",
  "gender": "female",
  "birthdate": "0000-10-31",
  "email": "janedoe@example.com",
  "picture": "http://example.com/janedoe/me.jpg",
  "https://my-app.example.com/groups": "My Group"
}
2 Likes