Option 1. Using the access token payload
This guide describes how to add custom claims to SuperTokens Access Tokens.
If you are implementing Unified Login, which makes use of OAuth2 Access Tokens, you will have to check the separate guide.
Add custom claims to the access token payload
There are "protected" claims, reserved for standard or supertokens specific use-cases. Trying to overwrite them in createNewSession
or using mergeIntoAccessTokenPayload
will result in errors.
They are: sub
, iat
, exp
, sessionHandle
, refreshTokenHash1
, parentRefreshTokenHash1
, antiCsrfToken
There are two ways to add custom claims to the access token payload:
- During session creation
- Post session creation
During session creation
This is the most typical method of adding custom claims. A session is created when a user signs in or signs up, and we can add custom claims to their session by overriding the createNewSession
function as shown below:
import SuperTokens from "supertokens-node";
import Session from "supertokens-node/recipe/session";
SuperTokens.init({
supertokens: {
connectionURI: "...",
},
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
recipeList: [
// ...
Session.init({
override: {
functions: (originalImplementation) => {
return {
...originalImplementation,
createNewSession: async function (input) {
let userId = input.userId;
// This goes in the access token, and is available to read on the frontend.
input.accessTokenPayload = {
...input.accessTokenPayload,
someKey: "someValue",
};
return originalImplementation.createNewSession(input);
},
};
},
},
})
]
});
Post session creation
In this method, you can modify the access token payload of an existing session. There are two modes in this:
- With session verification (online mode)
- Without session verification (offline mode)
With session verification (online mode)
import express from "express";
import { verifySession } from "supertokens-node/recipe/session/framework/express";
import { SessionRequest } from "supertokens-node/framework/express";
let app = express();
app.post("/updateinfo", verifySession(), async (req: SessionRequest, res) => {
let session = req.session;
await session!.mergeIntoAccessTokenPayload(
{ newKey: "newValue" }
);
res.json({ message: "successfully updated access token payload" })
});
- We first require session verification in order to get the session object
- Using that object, we call the
mergeIntoAccessTokenPayload
with new content. This merges the update into the existing object, removing keys set to null in the root of the update object. - The result is that the access token is updated in the user's browser cookies. The change is instantly visible on the frontend and the subsequent backend API calls.
Without session verification (offline mode)
This method can be used to update the access token payload even if the user is not online.
import Session from "supertokens-node/recipe/session";
async function updateAccessTokenPayload() {
let userId = "...";
// we first get all the sessionHandles (string[]) for a user
let sessionHandles = await Session.getAllSessionHandlesForUser(userId);
// we update all the session's Access Token payloads for this user
sessionHandles.forEach(async (handle) => {
let currSessionInfo = await Session.getSessionInformation(handle);
if (currSessionInfo === undefined) {
return;
}
await Session.mergeIntoAccessTokenPayload(handle,
{ newKey: "newValue" }
);
})
}
Changes to the access token payload via this method are reflected in the session only once the session is refreshed.
Read the access token payload
Once the custom payload has been added to the session, you can access it on the backend and frontend in the following ways:
Reading the payload on the backend
With session verification (online mode)
This method can be used when the user is online and has sent an API request with their session tokens
import express from "express";
import { verifySession } from "supertokens-node/recipe/session/framework/express";
let app = express();
app.get("/myApi", verifySession(), async (req, res) => {
let session = req.session;
let accessTokenPayload = session.getAccessTokenPayload();
let customClaimValue = accessTokenPayload.customClaim
});
Without session verification (offline mode)
import Session from "supertokens-node/recipe/session";
async function someFunc() {
let userId = "...";
// we first get all the sessionHandles (string[]) for a user
let sessionHandles = await Session.getAllSessionHandlesForUser(userId);
sessionHandles.forEach(async (handle) => {
let currSessionInfo = await Session.getSessionInformation(handle)
if (currSessionInfo === undefined) {
return;
}
let accessTokenPayload = currSessionInfo.customClaimsInAccessTokenPayload;
let customClaimValue = accessTokenPayload.customClaim;
})
}