How do I store the logged in users in my own DB?

I’m using Django (DRF) as a rest backend and Nuxt on the frontend. I wish to store the logged in user in my DB because I have database tables that rely on the relation between a user and other tables. In the article Create Modern Applications with Django and Vue.js - Learn Here

the author writes

For most cases, you don’t need to store users in your database since Auth0 handles all of that for you including advanced features such as profiles. You can use a custom function that checks if a general (can be fake) user that you create exists and map it to all Auth0 users.

What does he mean? I obviously need to know the logged in user so I can do the correct queries.

What is the solution here? How should I store the logged in user in my db? Or are there other ways?

Many of our Django apps use a database to store application-specific data. You can certainly do that. The point of the article is that you can store more or less whatever data you want in the user_metadata and app_metadata objects in the Auth0 user profile, which will be sufficient for many applications. But if you app needs a back-end DB, then absolutely do that.

I would strongly suggest creating a custom UUID attribute in your Auth0 user profiles and then use that UUID as your primary key in your application database. Or, if you don’t want to create a custom UUID, use the Auth0 user_id field. Don’t use email address or username (if you have usernames enabled).

1 Like

Thanks! Are there any guides on how this is done? I can’t be the only one who still needs a database in the backend?

I can’t speak to the specifics of Django + your chosen DB (we have a number of Auth0-enabled Django apps with Postgresql DBs) but in general: your app will receive an ID token for the user with identifying information in it like the sub, and you can add additional claims to the ID token, like a UUID if you implement that. Once your ID token has the data you need, use the sub or the UUID or whatever else from the token as your primary key.

If you want to create a UUID, I have some Rules at the link below that show how to create it and how to add it to your ID token. I haven’t looked at these in a while but they should still work.

Hi @erikvmalmberg did you figure out the best practice for this (I’m also surprised this isn’t an issue everybody has).

I was considering creating a user in our DB in a hook however I’d be nervous about consistency issues, e.g. if we used “Pre User Registration” what happens if the auth0 user creation failed? or If we used " Post User Registration" what happens if our DB call failed :thinking:

Hi @riscarrott ,

Welcome to the Community! I would suggested skipping the hooks and letting your app create the database entry once it receives the ID token from Auth0. Make sure to use an immutable internal identifier in the database. You can use the sub claim which will be the Auth0 user_id or create your own per my uuid comments above.

1 Like

Thanks for helping on this one Mark!

HI @ markd

Sounds like a good idea as if the upsert into our DB fails we could just throw away the access token and avoid logging the user in, asking them to retry. This would then guarantee every logged in user has a user record in our DB.

Having said that, our applications are all SPAs currently so we wouldn’t reliably be able to deny the login if the upsert into our DB failed as the access token would have already been sent to the browser.

I guess this is a good use case for rules then e.g.

function syncUser(__user, __context, __callback) {
  const fetch = require('node-fetch');

  const API_GATEWAY_HOST = 'https://example.com/api';

  const main = async (user, context) => {
    // *upsert* the user into our DB
    const response = await fetch(`${API_GATEWAY_HOST}/users/`, {
      method: 'PUT',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
       Authorization: 'Bearer ${ACCESS_TOKEN}'
      },
      body: JSON.stringify({
        id: user.user_id,
        roles: user.roles,
        email: user.email,
        emailVerified: user.email_verified,
        name: user.name,
        firstName: user.first_name,
        lastName: user.last_name,
        nickname: user.nickname,
        picture: user.picture,
        locale: user.locale,
        updatedAt: user.updated_at,
        createdAt: user.created_at,
      }),
    });
    if (!response.ok) {
      throw new Error(`Failed to sync user: ${response.status}`);
    }
    return [user, context];
  };

  main(__user, __context)
    .then(([user, context]) => __callback(null, user, context))
    .catch(ex => __callback(ex));
}
1 Like

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