Skip to main content

User Impersonation

This allows you to login as another user in your application without entering their credentials. This is useful for testing purposes, or for customer support.

caution

Since this feature allows you to login as any user in your application, it should be protected to only allow admins or custom support staff to use it. You can use any method to protect this API. For example:

  • API Key
  • Session with an admin role
  • Only allowing certain IP addresses to query the API

In this guide, we will assume that you will be using the "Session with an admin role" approach.

We will implement this feature by creating a new API endpoint that accepts an email, phone number, or just a user ID and returns the session tokens for that user. On page reload, the admin will be logged in as the user they selected.

In order for this to work, admins will need to first login into the application as themselves. Once their session is created (just like any regular user's session), then they can call the API via a frontend UI that's only shown to them (you can detect the admin role on the frontend by seeing this guide).

Here is the API code (assuming that the input is an email ID):

import express from "express";
import { verifySession } from "supertokens-node/recipe/session/framework/express";
import Session from "supertokens-node/recipe/session";
import supertokens from "supertokens-node";
import UserRoles from "supertokens-node/recipe/userroles";

let app = express();

app.post(
"/impersonate",
verifySession({
overrideGlobalClaimValidators: async (globalValidators) => [
...globalValidators,
UserRoles.UserRoleClaim.validators.includes("admin")
],
}),
async (req, res) => {

let email = "..."; // read from request body

let user = await supertokens.listUsersByAccountInfo("public", {
email
});

if (user.length === 0) {
throw new Error("User does not exist");
}

await Session.createNewSession(req, res, "public", user[0].loginMethods[0].recipeUserId, {
isImpersonation: true,
});

/* a new session has been created.
* - an access & refresh token has been attached to the response's cookie
* - a new row has been inserted into the database for this new session
*/

res.json({ message: "Impersonation successful!" });
})
Multi Tenancy

Notice that we pass in the "public" tenantId to the function call above. This is the default tenantId in SuperTokens. If you are using the multi tenancy feature and want to login into a different tenant, you can replace "public" with the tenantId you want to login into.

You can fetch this tenantId based on the admin user's tenant (from their session), or you can pass it in the request body.

  • The API is supposed to be called from your frontend application such that our frontend SDKs' network interceptors are running.
  • In the API above, we first run session verification and make sure that the user has the admin role. If not, the API will return a 403 to the frontend.
  • We then fetch the target user based on their email ID. If the user does not exist, we throw an error (which you can map to a 400 status code).
  • We then create a new session using the target user's user ID. We pass in the isImpersonation flag as true in the access token payload so that we can detect this on the frontend and show a message to the admin user that they are now impersonating the target user (this is UI you would have to build if you want to). You can also use this custom access token payload to protect certain APIs which the admin cannot call, even if in impersonation mode. In the code we use isImpersonation, but you can use anything else you like. In fact, you can even add the admin user's user ID to the access token payload (with a key like adminUserId), for logging purposes.
  • The new session tokens will be attached to the response and overwrite the existing admin session. Cookies will be used if the request contains the st-auth-mode: "cookie" header, otherwise the mode will be header based auth. Since you would be calling this API via our frontend interceptors, you do not need to explicitly set this header since our frontend SDK does this on its own.
  • Once impersonated, the admin user will be able to logout of the target user's session by clicking on the sign out button of your app - nothing special needs to be done there.
Looking for older versions of the documentation?
Which UI do you use?
Custom UI
Pre built UI