Auth0 Home Blog Docs

Secure REST APIs in Node.js and extract user info from universal login

Hi everyone,
I secured my Express.js REST APIs using the instructions found on udemy tutorial (https://www.udemy.com/build-secure-apis-with-auth0-and-postman/), then I customized universal login to support Google and Facebook Social connections, now I would like to extract user login info (email) to use this field to populate a MongoDB collection. I have to use rules to accomplish this? Could anyone suggest a tutorial or an example code? Thanks in advance.

Just to confirm: I assume the MongoDB is hosted on your server, so you’re not referring to the Auth0 user store, which you see under Dashboard > Users & Roles > Users.
Further, I assume you want to populate the MongoDB collection in real-time once a user authenticates? (and not via cronjob by fetching the user info from the Auth0 Management API).

In this case, you are right, you can do this via Rules. However, it’s best to not open up your MongoDB directly but provide an API facade on your end where the Auth0 rules engine can communicate with in order to send the user info.

In order to get the email address, make sure it’s included in the scope parameter of your initial authorize request in your client application. So it should be something like: openid profile email.

function (user, context, callback) {
  const request = require('request');

  request.post({
    url: 'https://your-mongodb-api-facade/users',
    json: {
      email: user.email,  // <-- here you transfer the email address
      additional_params: ...,   // <-- ... most likely with other parameters, such as user.user_id
      [...]
    },
    timeout: 2000
  }, function (err, response, body){
    if (err) return callback(err);
    return callback(null, user, context);
  });
}

Note that this would be executed every time the user authenticates, not only at first signup. If you only need it once, you can check via:

if (context.stats.loginsCount === 1) {...}
1 Like

Thanks!
Your assumptions are right.
To be more clear, I would like to protect some Insert/Update/Delete REST APIs that expose a MongoDB collection using Universal Login in Auth0 but It would be great if I could extract user authenticated info (email) to populate one field of the mongoose model automatically without leaving to the client the possibility to provide any email it wants.
So the rule on Auth0 should only provide user email extracted from Social connector while is my mongoose (on my Node.js backend) model’s responsibility to fill the appropriate field.

Who is making these CRUD REST API calls? Is it your client application but on behalf of the currently logged in user?

The use case still doesn’t get 100% clear to me.
Remember, after the user authenticated, he gets back and ID and access token. Both could include the user’s email address and this can then not be tampered with, because the tokens are signed by the Authorization Server (Auth0).

When the access token is sent to the API for the CRUD API request (as bearer token), the backend could extract the email from the token, or is that too late in the process?

Wondering: why do you need to have the email address stored somewhere in your MongoDB instead of leaving everything identity related in Auth0?

My generic client is a Android/iOS App or a custom application running on Raspberry/Pc.
This clients have to perform CRUD operations on my MongoDB Server and for this I provide REST APIs some of which I want to secure.
I choose a bucket pattern schema for my MongoDB collection (since it consists of IoT data not directly saved by the IoT device but using an Android/iOS App that connects to the device gather the data and send it back to the backend).
Email field is useful for later analytics (find by email query pattern sort of).
Hope this clarify everything.
Thanks again for your prompt and kindly support.

Ok, so in this case, if your Android device sends the data to the backend, and the user has to be logged into the Android device, you can use the approach mentioned before.

Add the email address to the access token via custom claim…

… added to the token via rule, such as:

function (user, context, callback) {
  const namespace = 'https://any-namespace/';
  context.accessToken[namespace + 'email'] = user.email;
  callback(null, user, context);
}

and on the backend, when it receives the data from the Android client, with the access token in the request header, just extract the email address from the access token again.

1 Like

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.