Skip to content
Esc
navigateopen⌘Jpreview
Dashboard
On this page

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

Next.js router
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 { 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...

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

UI type
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();
  }
}

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

Next.js router
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 { 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)

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
    #

See also

API reference

API schema and response details