Initial setup
Overview
When you work with the UserRoles
recipe you should follow these steps:
The next sections show you the actual instructions on how to achieve this.
Before you start
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)
}
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.