Skip to main content

Initial setup

Overview

When you work with the UserRoles recipe you should follow these steps:

1Create a role and assign permissions to it
2Assign roles to users
3Protect frontend and backend routes by verifying that the user has the correct role and permissions

The next sections show you the actual instructions on how to achieve this.

Before you start

Multi Tenancy

In a multi tenant setup, roles, and permissions share across all tenants, however, the mapping of users to roles are on a per tenant level.

For example, if you create one role ("admin") and add permissions to it for read:all and write:all, this role can reuse across all tenants. If you have user ID user1 that has access to tenant1 and tenant2, you can give them the admin role in tenant1, but not in tenant2.

Steps

1. Initialize the recipe

import SuperTokens from "supertokens-node";
import UserRoles from "supertokens-node/recipe/userroles";

SuperTokens.init({
supertokens: {
connectionURI: "..."
},
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
recipeList: [
UserRoles.init(),
]
});

By default, the user roles recipe adds the roles and permission information into a user's session (if they have assigned roles & permissions). If you do not want roles or permissions information in the session, or want to manually add it yourself, you can provide the following input configs to the UserRoles.init function:

import UserRoles from "supertokens-node/recipe/userroles";

UserRoles.init({
skipAddingRolesToAccessToken: true,
skipAddingPermissionsToAccessToken: true,
})

2. Create roles and permissions

Roles and permissions are simple string values. They should represent entities and actions that are relevant to your business logic. To create them use the next code snippet as a reference. When you create a role you can also include the permissions that the role should have.

import UserRoles from "supertokens-node/recipe/userroles";

async function createRole() {
const response = await UserRoles.createNewRoleOrAddPermissions("user", ["read"]);

if (response.createdNewRole === false) {
// The role already exists
}
}

3. Assign roles to users

After you create a user account, you can assign roles to them. You can do this by overriding the authentication recipes with a function that calls the UserRoles API after a successful sign up. The next code snippet shows you what function to call to connect a user to a role. To figure out where to call that function, check the documentation for the authentication method that you use: passwordless, email-password or third-party.

import UserRoles from "supertokens-node/recipe/userroles";

async function addRoleToUser(userId: string) {
const response = await UserRoles.addRoleToUser("public", userId, "user");

if (response.status === "UNKNOWN_ROLE_ERROR") {
// No such role exists
return;
}

if (response.didUserAlreadyHaveRole === true) {
// The user already had the role
}
}

Assign roles to a session

If you want to associate a role to a user after you create a session, you can do this by manually calling the function described in the next code snippet. For information on how to access the session object that you need to pass to the function, check either the Verify Session or the Get Session documentation.

import {UserRoleClaim, PermissionClaim} from "supertokens-node/recipe/userroles";
import {SessionContainer} from "supertokens-node/recipe/session"

async function addRolesAndPermissionsToSession(session: SessionContainer) {
// we add the user's roles to the user's session
await session.fetchAndSetClaim(UserRoleClaim)

// we add the permissions of a user to the user's session
await session.fetchAndSetClaim(PermissionClaim)
}
Multi Tenancy

Whilst roles and permissions share across apps, the association of roles to users is on a per tenant level. If using SDK functions to add a role to a user, you can also pass in a tenantId to the function. This tells SuperTokens to add the role for that user for that tenant.

In the code examples above, the "public" tenantId goes in, which is the default tenantId for users. You can fetch the user's tenantId from their current session, or from their user object (which you can fetch using their userId).

Note that if you associate a role to a user ID for a tenant, and that user ID doesn't belong to that tenant, then the operation still succeeds.

See also