Can auth0 enforce single unique session per user

Is there anyway for auth0 to enforce a single unique session per user so multiple individuals cannot share a single set of user credentials simultaneously?

Still looking for a solution here - thanks!

It is possible but requires some effort on your part. Here’s how we did it:

Because our app requires users to be pre-registered and invited, we have a User collection in our DB. A sessionId field was added to the user.

A logon rule updates this sessionId value and passes it back to the client via app_metadata. All API calls from the client app pass this sessionId as a header.

Node middleware validates the sessionId (if someone else has logged on, then the sessionId has been updated by the logon rule). If the sessionId’s differ, then the middleware returns 401 - Unauthorized. On receiving this, the client logs the user out. Additionally the client pings an API endpoint (which does nothing) every 10 seconds, meaning that the user will be forcibly logged out if credentials are shared.

Hope this helps.

Regards,
Jeff

1 Like

Thanks a lot for sharing that with the rest of community @jeffeld!

1 Like

Here’s the rule. I’ve anonymised bits, so remember to put in your API path (and secure it) for updating the sessionId.

async function (user, context, callback) {

  // Should only be run for verified users
  if (!user.email) {
    console.log('User not verified');
    return callback(null, user, context);
  }

  const setSessionIdForUser = async (user) => {

    const url = `https://your_api.com/setSession/${user}`;
    console.log (url);

    return new Promise ((resolve) => {

      request.post (url, {}, (err, resp, body) => {
        if (resp.statusCode !== 200) {
          console.error ('Failure');
          return callback (new Error (`Error ${resp.statusCode} from setSession: ${body || err}`));
        }

        // console.log ('Body');
        // console.log (body);

        resolve (JSON.parse(body));
      });

    });

  };

  const {sessionId} = await setSessionIdForUser(user.email);

  user.app_metadata = user.app_metadata || {};
  user.app_metadata.sessionId = sessionId;

  console.log (`${user.email} app_metadata=`);
  console.log (user.app_metadata);

  auth0.users.updateAppMetadata (user.user_id, user.app_metadata)
    .then (() => {
      console.log ('Success');

      const ns = 'https://your_domain.com/';
      context.accessToken[`${ns}app_metadata`] = user.app_metadata;

      callback (null, user, context);
    })
    .catch ((err) => {
      console.error (err);
      callback (err);
    });

}
1 Like

Perfectly thanks for that!

1 Like

Awesome, thank you for this!

1 Like