Access Session Data
Learn how to access session data including JWT tokens, tenant IDs, and user sessions across different programming languages and frameworks.
Overview
The session data is accessible, both in the backend and on the frontend, after a user has successfully logged in. This guide shows you how to access different session properties.
Before you start
Access the JWT Token
On the backend
import express from "express";
import { verifySession } from "supertokens-node/recipe/session/framework/express";
let app = express();
app.get("/getJWT", verifySession(), async (req, res) => {
let session = req.session;
let jwt = session.getAccessToken();
res.json({ token: jwt });
});import Hapi from "@hapi/hapi";
import { verifySession } from "supertokens-node/recipe/session/framework/hapi";
import { SessionRequest } from "supertokens-node/framework/hapi";
let server = Hapi.server({ port: 8000 });
server.route({
path: "/getJWT",
method: "get",
options: {
pre: [
{
method: verifySession(),
},
],
},
handler: async (req: SessionRequest, res) => {
let session = req.session;
let jwt = session!.getAccessToken();
return res.response({ token: jwt }).code(200);
},
});import Fastify from "fastify";
import { verifySession } from "supertokens-node/recipe/session/framework/fastify";
let fastify = Fastify();
fastify.get(
"/getJWT",
{
preHandler: verifySession(),
},
(req, res) => {
let session = req.session;
let jwt = session.getAccessToken();
res.send({ token: jwt });
},
);import { verifySession } from "supertokens-node/recipe/session/framework/awsLambda";
import { SessionEvent } from "supertokens-node/framework/awsLambda";
async function getJWT(awsEvent: SessionEvent) {
let session = awsEvent.session;
let jwt = session!.getAccessToken();
return {
body: JSON.stringify({ token: jwt }),
statusCode: 200,
};
}
exports.handler = verifySession(getJWT);import KoaRouter from "koa-router";
import { verifySession } from "supertokens-node/recipe/session/framework/koa";
import { SessionContext } from "supertokens-node/framework/koa";
let router = new KoaRouter();
router.get("/getJWT", verifySession(), (ctx: SessionContext, next) => {
let session = ctx.session;
let jwt = session!.getAccessToken();
ctx.body = { token: jwt };
});import { inject, intercept } from "@loopback/core";
import { RestBindings, get, response } from "@loopback/rest";
import { verifySession } from "supertokens-node/recipe/session/framework/loopback";
import { SessionContext } from "supertokens-node/framework/loopback";
class GetJWT {
constructor(@inject(RestBindings.Http.CONTEXT) private ctx: SessionContext) {}
@get("/getJWT")
@intercept(verifySession())
@response(200)
handler() {
let session = this.ctx.session;
let jwt = session!.getAccessToken();
return { token: jwt };
}
}import { superTokensNextWrapper } from "supertokens-node/nextjs";
import { verifySession } from "supertokens-node/recipe/session/framework/express";
import { SessionRequest } from "supertokens-node/framework/express";
export default async function getJWT(req: SessionRequest, res: any) {
await superTokensNextWrapper(
async (next) => {
await verifySession()(req, res, next);
},
req,
res,
);
let session = req.session;
let jwt = session!.getAccessToken();
res.json({ token: jwt });
}import { Controller, Get, UseGuards, Session } from "@nestjs/common";
import { SessionContainer } from "supertokens-node/recipe/session";
import { AuthGuard } from "./auth/auth.guard";
@Controller()
export class ExampleController {
@Get("example")
@UseGuards(new AuthGuard())
async postExample(@Session() session: SessionContainer): Promise<{ token: any }> {
// For more information about "AuthGuard" and the "Session" decorator please read our NestJS guide.
const jwt = session.getAccessToken();
return { token: jwt };
}
}import (
"fmt"
"net/http"
"github.com/supertokens/supertokens-golang/recipe/session"
)
// We assume that you have wrapped this handler with session.VerifySession
func getJWT(w http.ResponseWriter, r *http.Request) {
// retrieve the session object as shown below
sessionContainer := session.GetSessionFromRequestContext(r.Context())
jwt := sessionContainer.GetAccessToken()
fmt.Println(jwt)
}from fastapi import Depends
from supertokens_python.recipe.session import SessionContainer
from supertokens_python.recipe.session.framework.fastapi import verify_session
@app.get('/getJWT')
async def get_jwt(session: SessionContainer = Depends(verify_session())):
current_jwt = session.get_access_token()
print(current_jwt) # TODO...from flask import g
from supertokens_python.recipe.session import SessionContainer
from supertokens_python.recipe.session.framework.flask import verify_session
@app.route('/getJWT', methods=['GET'])
@verify_session()
def get_jwt():
session: SessionContainer = g.supertokens
current_jwt = session.get_access_token()
print(current_jwt) # TODO...from typing import cast
from django.http import HttpRequest
from supertokens_python.recipe.session import SessionContainer
from supertokens_python.recipe.session.framework.django.asyncio import verify_session
@verify_session()
async def get_jwt(request: HttpRequest):
session: SessionContainer = cast(SessionContainer, request.supertokens)
current_jwt = session.get_access_token()
print(current_jwt) # TODO...import { NextResponse, NextRequest } from "next/server";
import SuperTokens from "supertokens-node";
import { withSession } from "supertokens-node/nextjs";
import { backendConfig } from "@/app/config/backend";
SuperTokens.init(backendConfig());
export function POST(request: NextRequest) {
return withSession(request, async (err, session) => {
if (err) {
return NextResponse.json(err, { status: 500 });
}
let jwt = session!.getAccessToken();
return NextResponse.json({ token: jwt });
});
}On the frontend
1. Enable exposeAccessTokenToFrontendInCookieBasedAuth
When using cookie based auth, by default, the access token is not readable by the SDK on the frontend (since it’s stored as httpOnly cookie).
To enable this, you need to set the exposeAccessTokenToFrontendInCookieBasedAuth parameter to true.
import SuperTokens from "supertokens-node";
import Session from "supertokens-node/recipe/session";
SuperTokens.init({
supertokens: {
connectionURI: "...",
},
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "...",
},
recipeList: [
Session.init({
exposeAccessTokenToFrontendInCookieBasedAuth: true,
}),
],
});import (
"github.com/supertokens/supertokens-golang/recipe/session"
"github.com/supertokens/supertokens-golang/recipe/session/sessmodels"
"github.com/supertokens/supertokens-golang/supertokens"
)
func main() {
supertokens.Init(supertokens.TypeInput{
RecipeList: []supertokens.Recipe{
session.Init(&sessmodels.TypeInput{
ExposeAccessTokenToFrontendInCookieBasedAuth: true,
}),
},
})
}from supertokens_python import InputAppInfo, init
from supertokens_python.recipe import session
init(
app_info=InputAppInfo(
api_domain="...", app_name="...", website_domain="..."),
framework='...',
recipe_list=[
session.init(
expose_access_token_to_frontend_in_cookie_based_auth=True
)
]
)2. Read the access token
import Session from "supertokens-auth-react/recipe/session";
async function getJWT() {
if (await Session.doesSessionExist()) {
let userId = await Session.getUserId();
let jwt = await Session.getAccessToken();
}
}import Session from "supertokens-web-js/recipe/session";
async function getJWT() {
if (await Session.doesSessionExist()) {
let userId = await Session.getUserId();
let jwt = await Session.getAccessToken();
}
}import Session from "supertokens-web-js/recipe/session";
async function getJWT() {
if (await Session.doesSessionExist()) {
let userId = await Session.getUserId();
let jwt = await Session.getAccessToken();
}
}async function getJWT() {
if (await supertokensSession.doesSessionExist()) {
let userId = await supertokensSession.getUserId();
let jwt = await supertokensSession.getAccessToken();
}
}import SuperTokens from "supertokens-react-native";
async function getJWT() {
if (await SuperTokens.doesSessionExist()) {
let userId = await SuperTokens.getUserId();
let jwt = await SuperTokens.getAccessToken();
}
}import android.app.Application
import com.supertokens.session.SuperTokens
import org.json.JSONObject
class MainApplication: Application() {
fun getJWT() {
val jwt: String? = SuperTokens.getAccessToken(this);
}
}import UIKit
import SuperTokensIOS
fileprivate class ViewController: UIViewController {
func getJWT() {
let jwt: String? = SuperTokens.getAccessToken()
// Use `jwt` however you like
}
}import 'package:supertokens_flutter/supertokens.dart';
Future<void> getJWT() async {
var jwt = await SuperTokens.getAccessToken();
if (jwt != null) {
// Use `jwt` however you like
}
}Access the Tenant ID
The session’s access token payload contains the tenant ID in the tId claim. You can access it in the following way:
On the backend
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("/like-comment", verifySession(), (req: SessionRequest, res) => {
let tenantId = req.session!.getTenantId();
//....
});import Hapi from "@hapi/hapi";
import { verifySession } from "supertokens-node/recipe/session/framework/hapi";
import { SessionRequest } from "supertokens-node/framework/hapi";
let server = Hapi.server({ port: 8000 });
server.route({
path: "/like-comment",
method: "post",
options: {
pre: [
{
method: verifySession(),
},
],
},
handler: async (req: SessionRequest, res) => {
let tenantId = req.session!.getTenantId();
//...
},
});import Fastify from "fastify";
import { verifySession } from "supertokens-node/recipe/session/framework/fastify";
import { SessionRequest } from "supertokens-node/framework/fastify";
let fastify = Fastify();
fastify.post(
"/like-comment",
{
preHandler: verifySession(),
},
(req: SessionRequest, res) => {
let tenantId = req.session!.getTenantId();
//....
},
);import { verifySession } from "supertokens-node/recipe/session/framework/awsLambda";
import { SessionEventV2 } from "supertokens-node/framework/awsLambda";
async function likeComment(awsEvent: SessionEventV2) {
let tenantId = awsEvent.session!.getTenantId();
//....
}
exports.handler = verifySession(likeComment);import KoaRouter from "koa-router";
import { verifySession } from "supertokens-node/recipe/session/framework/koa";
import { SessionContext } from "supertokens-node/framework/koa";
let router = new KoaRouter();
router.post("/like-comment", verifySession(), (ctx: SessionContext, next) => {
let tenantId = ctx.session!.getTenantId();
//....
});import { inject, intercept } from "@loopback/core";
import { RestBindings, MiddlewareContext, post, response } from "@loopback/rest";
import { verifySession } from "supertokens-node/recipe/session/framework/loopback";
import { SessionContext } from "supertokens-node/framework/loopback";
class LikeComment {
constructor(@inject(RestBindings.Http.CONTEXT) private ctx: MiddlewareContext) {}
@post("/like-comment")
@intercept(verifySession())
@response(200)
handler() {
let tenantId = (this.ctx as SessionContext).session!.getTenantId();
//....
}
}import { superTokensNextWrapper } from "supertokens-node/nextjs";
import { verifySession } from "supertokens-node/recipe/session/framework/express";
import { SessionRequest } from "supertokens-node/framework/express";
export default async function likeComment(req: SessionRequest, res: any) {
await superTokensNextWrapper(
async (next) => {
await verifySession()(req, res, next);
},
req,
res,
);
let tenantId = req.session!.getTenantId();
//....
}import { Controller, Post, UseGuards, Session } from "@nestjs/common";
import { SessionContainer } from "supertokens-node/recipe/session";
import { AuthGuard } from "./auth/auth.guard";
@Controller()
export class ExampleController {
@Post("example")
@UseGuards(new AuthGuard()) // For more information about this guard please read our NestJS guide.
async postExample(@Session() session: SessionContainer): Promise<boolean> {
let tenantId = session.getTenantId();
//....
return true;
}
}import (
"fmt"
"net/http"
"github.com/supertokens/supertokens-golang/recipe/session"
)
func main() {
_ = http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
// Wrap the API handler in session.VerifySession
session.VerifySession(nil, likeCommentAPI).ServeHTTP(rw, r)
})
}
func likeCommentAPI(w http.ResponseWriter, r *http.Request) {
// retrieve the session object as shown below
sessionContainer := session.GetSessionFromRequestContext(r.Context())
tenantID := sessionContainer.GetTenantId()
fmt.Println(tenantID)
}import (
"fmt"
"net/http"
"github.com/gin-gonic/gin"
"github.com/supertokens/supertokens-golang/recipe/session"
"github.com/supertokens/supertokens-golang/recipe/session/sessmodels"
)
func main() {
router := gin.New()
// Wrap the API handler in session.VerifySession
router.POST("/likecomment", verifySession(nil), likeCommentAPI)
}
// This is a function that wraps the supertokens verification function
// to work the gin
func verifySession(options *sessmodels.VerifySessionOptions) gin.HandlerFunc {
return func(c *gin.Context) {
session.VerifySession(options, func(rw http.ResponseWriter, r *http.Request) {
c.Request = c.Request.WithContext(r.Context())
c.Next()
})(c.Writer, c.Request)
// we call Abort so that the next handler in the chain is not called, unless we call Next explicitly
c.Abort()
}
}
func likeCommentAPI(c *gin.Context) {
// retrieve the session object as shown below
sessionContainer := session.GetSessionFromRequestContext(c.Request.Context())
tenantID := sessionContainer.GetTenantId()
fmt.Println(tenantID)
}import (
"fmt"
"net/http"
"github.com/go-chi/chi"
"github.com/supertokens/supertokens-golang/recipe/session"
)
func main() {
r := chi.NewRouter()
// Wrap the API handler in session.VerifySession
r.Post("/likecomment", session.VerifySession(nil, likeCommentAPI))
}
func likeCommentAPI(w http.ResponseWriter, r *http.Request) {
// retrieve the session object as shown below
sessionContainer := session.GetSessionFromRequestContext(r.Context())
tenantID := sessionContainer.GetTenantId()
fmt.Println(tenantID)
}import (
"fmt"
"net/http"
"github.com/gorilla/mux"
"github.com/supertokens/supertokens-golang/recipe/session"
)
func main() {
router := mux.NewRouter()
// Wrap the API handler in session.VerifySession
router.HandleFunc("/likecomment", session.VerifySession(nil, likeCommentAPI)).Methods(http.MethodPost)
}
func likeCommentAPI(w http.ResponseWriter, r *http.Request) {
// retrieve the session object as shown below
sessionContainer := session.GetSessionFromRequestContext(r.Context())
tenantID := sessionContainer.GetTenantId()
fmt.Println(tenantID)
}from fastapi import Depends
from supertokens_python.recipe.session import SessionContainer
from supertokens_python.recipe.session.framework.fastapi import verify_session
@app.get('/getTenantId')
async def get_tenant_id(session: SessionContainer = Depends(verify_session())):
tenant_id = session.get_tenant_id()
print(tenant_id)from flask import g
from supertokens_python.recipe.session import SessionContainer
from supertokens_python.recipe.session.framework.flask import verify_session
@app.route('/getTenantId', methods=['GET'])
@verify_session()
def get_tenant_id():
session: SessionContainer = g.supertokens
tenant_id = session.get_tenant_id()
print(tenant_id)from typing import cast
from django.http import HttpRequest
from supertokens_python.recipe.session import SessionContainer
from supertokens_python.recipe.session.framework.django.asyncio import verify_session
@verify_session()
async def get_tenant_id(request: HttpRequest):
session: SessionContainer = cast(SessionContainer, request.supertokens)
tenant_id = session.get_tenant_id()
print(tenant_id)import { NextResponse, NextRequest } from "next/server";
import SuperTokens from "supertokens-node";
import { withSession } from "supertokens-node/nextjs";
import { backendConfig } from "@/app/config/backend";
SuperTokens.init(backendConfig());
export function POST(request: NextRequest) {
return withSession(request, async (err, session) => {
if (err) {
return NextResponse.json(err, { status: 500 });
}
let tenantId = session!.getTenantId();
//....
return NextResponse.json({});
});
}On the frontend
You can read the tenant ID on the frontend by adding the tId claim from the access token payload.
Fetch all user sessions
Given a user ID, you can fetch all sessions that are active for that user in the following way:
import Session from "supertokens-node/recipe/session";
async function getSessions() {
let userId = "someUserId"; // fetch somehow
// sessionHandles is string[]
let sessionHandles = await Session.getAllSessionHandlesForUser(userId);
sessionHandles.forEach((handle) => {
/* we can do the following with the handle:
* - revoke this session
* - change access token payload or session data
* - fetch access token payload or session data
*/
});
}import (
"fmt"
"github.com/supertokens/supertokens-golang/recipe/session"
)
func main() {
// sessionHandles is string[]
tenantId := "public"
sessionHandles, err := session.GetAllSessionHandlesForUser("someUserId", &tenantId)
if err != nil {
// TODO: handle error
return
}
for _, currSessionHandle := range sessionHandles {
/* we can do the following with the currSessionHandle:
* - revoke this session
* - change access token payload or session data
* - fetch access token payload or session data
*/
fmt.Println(currSessionHandle)
}
}from supertokens_python.recipe.session.asyncio import get_all_session_handles_for_user
async def some_func():
# session_handles is List[string]
session_handles = await get_all_session_handles_for_user("someUserId")
for _ in session_handles:
pass # TODO
#
# we can do the following with the session_handle:
# - revoke this session
# - change JWT payload or session data
# - fetch JWT payload or session data
#from supertokens_python.recipe.session.syncio import get_all_session_handles_for_user
# session_handles is List[string]
session_handles = get_all_session_handles_for_user("someUserId")
for session_handle in session_handles:
pass # TODO
#
# we can do the following with the session_handle:
# - revoke this session
# - change JWT payload or session data
# - fetch JWT payload or session data
#