Using the verifySession middleware
verifySession
middleware#
Verifying a session using the For your APIs that require a user to be logged in, use the verifySession
middleware:
- NodeJS
- GoLang
- Python
- Express
- Hapi
- Fastify
- Koa
- Loopback
- AWS Lambda / Netlify
- Next.js
- NestJS
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 userId = req.session!.getUserId(); //....});
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 userId = req.session!.getUserId(); //... }})
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 userId = req.session!.getUserId(); //....});
import { verifySession } from "supertokens-node/recipe/session/framework/awsLambda";import { SessionEventV2 } from "supertokens-node/framework/awsLambda";
async function likeComment(awsEvent: SessionEventV2) { let userId = awsEvent.session!.getUserId(); //....};
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 userId = ctx.session!.getUserId(); //....});
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 userId = (this.ctx as SessionContext).session!.getUserId(); //.... }}
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 userId = req.session!.getUserId(); //....}
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 userId = session.getUserId();
//.... return true; }}
- Chi
- net/http
- Gin
- Mux
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())
userID := sessionContainer.GetUserID()
fmt.Println(userID)}
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 ginfunc 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())
userID := sessionContainer.GetUserID()
fmt.Println(userID)}
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())
userID := sessionContainer.GetUserID()
fmt.Println(userID)}
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())
userID := sessionContainer.GetUserID()
fmt.Println(userID)}
- FastAPI
- Flask
- Django
from supertokens_python.recipe.session.framework.fastapi import verify_sessionfrom supertokens_python.recipe.session import SessionContainerfrom fastapi import Depends
@app.post('/like_comment') async def like_comment(session: SessionContainer = Depends(verify_session())): user_id = session.get_user_id()
print(user_id)
from supertokens_python.recipe.session.framework.flask import verify_sessionfrom supertokens_python.recipe.session import SessionContainerfrom flask import g
@app.route('/update-jwt', methods=['POST']) @verify_session()def like_comment(): session: SessionContainer = g.supertokens
user_id = session.get_user_id()
print(user_id)
from supertokens_python.recipe.session.framework.django.asyncio import verify_sessionfrom django.http import HttpRequestfrom supertokens_python.recipe.session import SessionContainer
@verify_session()async def like_comment(request: HttpRequest): session: SessionContainer = request.supertokens
user_id = session.get_user_id() print(user_id)
session
object#
The This object exposes the following functions:
getHandle
: Returns thesessionHandle
for this session. This is a constant, unique string per session that never changes for its session.getUserId
: Returns the userId of logged in usergetSessionData
: Returns the session data (stored in the db) that is associated with the sessionupdateSessionData
: Set a new JSON object to the session data (stored in the db)getAccessTokenPayload
: Returns the access token's payload for this session.mergeIntoAccessTokenPayload
: Adds key / values into a JSON object in the access token. Set a key tonull
to remove it from the payload.revokeSession
: Destroys this session in the db and on the frontendgetTimeCreated
: Returns the time in milliseconds of when this session was createdgetExpiry
: Returns the time in milliseconds of when this session will expire if not refreshed.getAccessToken
: Returns the rawstring
access token
#
Optional session verificationSometimes, you want an API to be accessible even if there is no session. In that case, you can use the sessionRequired
flag:
- NodeJS
- GoLang
- Python
- Express
- Hapi
- Fastify
- Koa
- Loopback
- AWS Lambda / Netlify
- Next.js
- NestJS
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({sessionRequired: false}), (req: SessionRequest, res) => { if (req.session !== undefined) { let userId = req.session.getUserId(); } else { // user is not logged in... } });
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({ sessionRequired: false }) }, ], }, handler: async (req: SessionRequest, res) => { if (req.session !== undefined) { let userId = req.session.getUserId(); } else { // user is not logged in... } }})
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({ sessionRequired: false }),}, (req: SessionRequest, res) => { if (req.session !== undefined) { let userId = req.session.getUserId(); } else { // user is not logged in... }});
import { verifySession } from "supertokens-node/recipe/session/framework/awsLambda";import { SessionEventV2 } from "supertokens-node/framework/awsLambda";
async function likeComment(awsEvent: SessionEventV2) { if (awsEvent.session !== undefined) { let userId = awsEvent.session.getUserId(); } else { // user is not logged in... }};
exports.handler = verifySession(likeComment, { sessionRequired: false });
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({ sessionRequired: false }), (ctx: SessionContext, next) => { if (ctx.session !== undefined) { let userId = ctx.session.getUserId(); } else { // user is not logged in... } });
import { inject, intercept } from "@loopback/core";import { RestBindings, MiddlewareContext, post, response } from "@loopback/rest";import { verifySession } from "supertokens-node/recipe/session/framework/loopback";import Session from "supertokens-node/recipe/session";import { SessionContext } from "supertokens-node/framework/loopback";
class LikeComment { constructor(@inject(RestBindings.Http.CONTEXT) private ctx: MiddlewareContext) { } @post("/like-comment") @intercept(verifySession({ sessionRequired: false })) @response(200) handler() { let session = (this.ctx as SessionContext).session; if (session !== undefined) { let userId = session.getUserId(); } else { // user is not logged in... } }}
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: any, res: any) { await superTokensNextWrapper( async (next) => { await verifySession({ sessionRequired: false })(req, res, next); }, req, res )
let session = (req as SessionRequest).session;
if (session !== undefined) { let userId = session.getUserId(); // session exists } else { // session doesn't exist } //....}
import { Controller, Post, UseGuards, Session } from "@nestjs/common";import { SessionContainer } from "supertokens-node/recipe/session";import { OptionalAuthGuard } from './auth/optionalAuth.guard';
@Controller()export class ExampleController { @Post('example') @UseGuards(new OptionalAuthGuard()) // For more information about this guard please read our NestJS guide. async postExample(@Session() session: SessionContainer): Promise<boolean> { if (session !== undefined) { let userId = session.getUserId(); // session exists } else { // session doesn't exist }
//.... return true; }}
- Chi
- net/http
- Gin
- Mux
import ( "fmt" "net/http"
"github.com/supertokens/supertokens-golang/recipe/session" "github.com/supertokens/supertokens-golang/recipe/session/sessmodels")
func main() {
_ = http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { // Wrap the API handler in session.VerifySession sessionRequired := false session.VerifySession(&sessmodels.VerifySessionOptions{ SessionRequired: &sessionRequired, }, likeCommentAPI).ServeHTTP(rw, r) })}
func likeCommentAPI(w http.ResponseWriter, r *http.Request) { // retrieve the session object as shown below sessionContainer := session.GetSessionFromRequestContext(r.Context())
userID := sessionContainer.GetUserID()
fmt.Println(userID)}
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 sessionRequired := false router.POST("/likecomment", verifySession(&sessmodels.VerifySessionOptions{ SessionRequired: &sessionRequired, }), likeCommentAPI)}
// This is a function that wraps the supertokens verification function// to work the ginfunc 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())
userID := sessionContainer.GetUserID()
fmt.Println(userID)}
import ( "fmt" "net/http"
"github.com/go-chi/chi" "github.com/supertokens/supertokens-golang/recipe/session" "github.com/supertokens/supertokens-golang/recipe/session/sessmodels")
func main() { r := chi.NewRouter()
// Wrap the API handler in session.VerifySession sessionRequired := false r.Post("/likecomment", session.VerifySession(&sessmodels.VerifySessionOptions{ SessionRequired: &sessionRequired, }, likeCommentAPI))}
func likeCommentAPI(w http.ResponseWriter, r *http.Request) { // retrieve the session object as shown below sessionContainer := session.GetSessionFromRequestContext(r.Context())
userID := sessionContainer.GetUserID()
fmt.Println(userID)}
import ( "fmt" "net/http"
"github.com/gorilla/mux" "github.com/supertokens/supertokens-golang/recipe/session" "github.com/supertokens/supertokens-golang/recipe/session/sessmodels")
func main() { router := mux.NewRouter()
// Wrap the API handler in session.VerifySession sessionRequired := false router.HandleFunc("/likecomment", session.VerifySession(&sessmodels.VerifySessionOptions{ SessionRequired: &sessionRequired, }, likeCommentAPI)).Methods(http.MethodPost)}
func likeCommentAPI(w http.ResponseWriter, r *http.Request) { // retrieve the session object as shown below sessionContainer := session.GetSessionFromRequestContext(r.Context())
userID := sessionContainer.GetUserID()
fmt.Println(userID)}
- FastAPI
- Flask
- Django
from supertokens_python.recipe.session.framework.fastapi import verify_sessionfrom fastapi import Dependsfrom supertokens_python.recipe.session import SessionContainer
@app.post('/like_comment') async def like_comment(session: SessionContainer = Depends(verify_session(session_required=False))): if session is not None: user_id = session.get_user_id() print(user_id) # TODO.. else: pass # user is not logged in
from supertokens_python.recipe.session.framework.flask import verify_sessionfrom supertokens_python.recipe.session import SessionContainerfrom typing import Unionfrom flask import g
@app.route('/update-jwt', methods=['POST']) @verify_session(session_required=False)def like_comment(): session: Union[SessionContainer, None] = g.supertokens
if session is not None: user_id = session.get_user_id() print(user_id) # TODO.. else: pass # user is not logged in
from supertokens_python.recipe.session.framework.django.asyncio import verify_sessionfrom django.http import HttpRequestfrom supertokens_python.recipe.session import SessionContainerfrom typing import Union
@verify_session(session_required=False)async def like_comment(request: HttpRequest): session: Union[None, SessionContainer] = request.supertokens if session is not None: user_id = session.get_user_id() print(user_id) # TODO.. else: pass # user is not logged in
#
Verifying the claims of a sessionSometimes, you may also want to check if there are certain claims in the session as part of the verification process. For example, you may want to check that the session has the admin
role claim for certain APIs, or that the user has completed 2FA.
This can be done using our session claims validator feature. Let's take an example of using the user roles claim to check if the session has the admin claim:
- NodeJS
- GoLang
- Python
- Express
- Hapi
- Fastify
- Koa
- Loopback
- AWS Lambda / Netlify
- Next.js
- NestJS
import { verifySession } from "supertokens-node/recipe/session/framework/express";import express from "express";import { SessionRequest } from "supertokens-node/framework/express";import UserRoles from "supertokens-node/recipe/userroles";
let app = express();
app.post( "/update-blog", verifySession({ overrideGlobalClaimValidators: async (globalValidators) => [ ...globalValidators, UserRoles.UserRoleClaim.validators.includes("admin"), // UserRoles.PermissionClaim.validators.includes("edit") ], }), async (req: SessionRequest, res) => { // All validator checks have passed and the user is an admin. });
import Hapi from "@hapi/hapi";import { verifySession } from "supertokens-node/recipe/session/framework/hapi";import {SessionRequest} from "supertokens-node/framework/hapi";import UserRoles from "supertokens-node/recipe/userroles";
let server = Hapi.server({ port: 8000 });
server.route({ path: "/update-blog", method: "post", options: { pre: [ { method: verifySession({ overrideGlobalClaimValidators: async (globalValidators) => [ ...globalValidators, UserRoles.UserRoleClaim.validators.includes("admin"), // UserRoles.PermissionClaim.validators.includes("edit") ], }), }, ], }, handler: async (req: SessionRequest, res) => { // All validator checks have passed and the user is an admin. }})
import Fastify from "fastify";import { verifySession } from "supertokens-node/recipe/session/framework/fastify";import { SessionRequest } from "supertokens-node/framework/fastify";import UserRoles from "supertokens-node/recipe/userroles";
let fastify = Fastify();
fastify.post("/update-blog", { preHandler: verifySession({ overrideGlobalClaimValidators: async (globalValidators) => [ ...globalValidators, UserRoles.UserRoleClaim.validators.includes("admin"), // UserRoles.PermissionClaim.validators.includes("edit") ], }),}, async (req: SessionRequest, res) => { // All validator checks have passed and the user is an admin.});
import { verifySession } from "supertokens-node/recipe/session/framework/awsLambda";import { SessionEvent } from "supertokens-node/framework/awsLambda";import UserRoles from "supertokens-node/recipe/userroles";
async function updateBlog(awsEvent: SessionEvent) { // All validator checks have passed and the user is an admin.};
exports.handler = verifySession(updateBlog, { overrideGlobalClaimValidators: async (globalValidators) => ([ ...globalValidators, UserRoles.UserRoleClaim.validators.includes("admin"), // UserRoles.PermissionClaim.validators.includes("edit") ])});
import KoaRouter from "koa-router";import { verifySession } from "supertokens-node/recipe/session/framework/koa";import {SessionContext} from "supertokens-node/framework/koa";import UserRoles from "supertokens-node/recipe/userroles";
let router = new KoaRouter();
router.post("/update-blog", verifySession({ overrideGlobalClaimValidators: async (globalValidators) => ([ ...globalValidators, UserRoles.UserRoleClaim.validators.includes("admin"), // UserRoles.PermissionClaim.validators.includes("edit") ]) }), async (ctx: SessionContext, next) => { // All validator checks have passed and the user is an admin.});
import { inject, intercept } from "@loopback/core";import { RestBindings, MiddlewareContext, post, response } from "@loopback/rest";import { verifySession } from "supertokens-node/recipe/session/framework/loopback";import Session from "supertokens-node/recipe/session";import UserRoles from "supertokens-node/recipe/userroles";
class SetRole { constructor(@inject(RestBindings.Http.CONTEXT) private ctx: MiddlewareContext) { } @post("/update-blog") @intercept(verifySession({ overrideGlobalClaimValidators: async (globalValidators) => ([ ...globalValidators, UserRoles.UserRoleClaim.validators.includes("admin"), // UserRoles.PermissionClaim.validators.includes("edit") ]) })) @response(200) async handler() { // All validator checks have passed and the user is an admin. }}
import { superTokensNextWrapper } from 'supertokens-node/nextjs'import { verifySession } from "supertokens-node/recipe/session/framework/express";import { SessionRequest } from "supertokens-node/framework/express";import UserRoles from "supertokens-node/recipe/userroles";
export default async function setRole(req: SessionRequest, res: any) { await superTokensNextWrapper( async (next) => { await verifySession({ overrideGlobalClaimValidators: async (globalValidators) => ([ ...globalValidators, UserRoles.UserRoleClaim.validators.includes("admin"), // UserRoles.PermissionClaim.validators.includes("edit") ]) })(req, res, next); }, req, res ) // All validator checks have passed and the user is an admin.}
import { Controller, Post, UseGuards, Request, Response, Session } from "@nestjs/common";import { SessionContainer, SessionClaimValidator } from "supertokens-node/recipe/session";import { AuthGuard } from './auth/auth.guard';import UserRoles from "supertokens-node/recipe/userroles";
@Controller()export class ExampleController { @Post('example') @UseGuards(new AuthGuard({ overrideGlobalClaimValidators: async (globalValidators: SessionClaimValidator[]) => ([ ...globalValidators, UserRoles.UserRoleClaim.validators.includes("admin"), // UserRoles.PermissionClaim.validators.includes("edit") ]) })) async postExample(@Session() session: SessionContainer): Promise<boolean> { // All validator checks have passed and the user is an admin. return true; }}
- Chi
- net/http
- Gin
- Mux
import ( "net/http"
"github.com/supertokens/supertokens-golang/recipe/userroles/userrolesclaims" "github.com/supertokens/supertokens-golang/recipe/session" "github.com/supertokens/supertokens-golang/recipe/session/claims" "github.com/supertokens/supertokens-golang/recipe/session/sessmodels" "github.com/supertokens/supertokens-golang/supertokens")
func main() { _ = http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { session.VerifySession(&sessmodels.VerifySessionOptions{ OverrideGlobalClaimValidators: func(globalClaimValidators []claims.SessionClaimValidator, sessionContainer sessmodels.SessionContainer, userContext supertokens.UserContext) ([]claims.SessionClaimValidator, error) { globalClaimValidators = append(globalClaimValidators, userrolesclaims.UserRoleClaimValidators.Includes("admin", nil, nil)) return globalClaimValidators, nil }, }, exampleAPI).ServeHTTP(rw, r) })}
func exampleAPI(w http.ResponseWriter, r *http.Request) { // TODO: session is verified and all validators have passed..}
import ( "net/http"
"github.com/gin-gonic/gin" "github.com/supertokens/supertokens-golang/recipe/userroles/userrolesclaims" "github.com/supertokens/supertokens-golang/recipe/session" "github.com/supertokens/supertokens-golang/recipe/session/claims" "github.com/supertokens/supertokens-golang/recipe/session/sessmodels" "github.com/supertokens/supertokens-golang/supertokens")
func main() { router := gin.New()
// Wrap the API handler in session.VerifySession router.POST("/likecomment", verifySession(&sessmodels.VerifySessionOptions{ OverrideGlobalClaimValidators: func(globalClaimValidators []claims.SessionClaimValidator, sessionContainer sessmodels.SessionContainer, userContext supertokens.UserContext) ([]claims.SessionClaimValidator, error) { globalClaimValidators = append(globalClaimValidators, userrolesclaims.UserRoleClaimValidators.Includes("admin", nil, nil)) return globalClaimValidators, nil }, }), exampleAPI)}
// This is a function that wraps the supertokens verification function// to work the ginfunc 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 exampleAPI(c *gin.Context) { // TODO: session is verified and all claim validators pass.}
import ( "net/http"
"github.com/go-chi/chi" "github.com/supertokens/supertokens-golang/recipe/userroles/userrolesclaims" "github.com/supertokens/supertokens-golang/recipe/session" "github.com/supertokens/supertokens-golang/recipe/session/claims" "github.com/supertokens/supertokens-golang/recipe/session/sessmodels" "github.com/supertokens/supertokens-golang/supertokens")
func main() { r := chi.NewRouter()
// Wrap the API handler in session.VerifySession r.Post("/likecomment", session.VerifySession(&sessmodels.VerifySessionOptions{ OverrideGlobalClaimValidators: func(globalClaimValidators []claims.SessionClaimValidator, sessionContainer sessmodels.SessionContainer, userContext supertokens.UserContext) ([]claims.SessionClaimValidator, error) { globalClaimValidators = append(globalClaimValidators, userrolesclaims.UserRoleClaimValidators.Includes("admin", nil, nil)) return globalClaimValidators, nil }, }, exampleAPI))}
func exampleAPI(w http.ResponseWriter, r *http.Request) { // TODO: session is verified and all claim validators pass.}
import ( "net/http"
"github.com/gorilla/mux" "github.com/supertokens/supertokens-golang/recipe/userroles/userrolesclaims" "github.com/supertokens/supertokens-golang/recipe/session" "github.com/supertokens/supertokens-golang/recipe/session/claims" "github.com/supertokens/supertokens-golang/recipe/session/sessmodels" "github.com/supertokens/supertokens-golang/supertokens")
func main() { router := mux.NewRouter()
// Wrap the API handler in session.VerifySession router.HandleFunc("/likecomment", session.VerifySession(&sessmodels.VerifySessionOptions{ OverrideGlobalClaimValidators: func(globalClaimValidators []claims.SessionClaimValidator, sessionContainer sessmodels.SessionContainer, userContext supertokens.UserContext) ([]claims.SessionClaimValidator, error) { globalClaimValidators = append(globalClaimValidators, userrolesclaims.UserRoleClaimValidators.Includes("admin", nil, nil)) return globalClaimValidators, nil }, }, exampleAPI)).Methods(http.MethodPost)}
func exampleAPI(w http.ResponseWriter, r *http.Request) { // TODO: session is verified and all claim validators pass.}
- FastAPI
- Flask
- Django
from supertokens_python.recipe.session.framework.fastapi import verify_sessionfrom supertokens_python.recipe.userroles import UserRoleClaimfrom supertokens_python.recipe.session import SessionContainerfrom fastapi import Depends
@app.post('/like_comment') async def like_comment(session: SessionContainer = Depends( verify_session( # We add the UserRoleClaim's includes validator override_global_claim_validators=lambda global_validators, session, user_context: global_validators + \ [UserRoleClaim.validators.includes("admin")] ))): # All validator checks have passed and the user has a verified email address pass
from supertokens_python.recipe.session.framework.flask import verify_sessionfrom supertokens_python.recipe.userroles import UserRoleClaim
@app.route('/update-jwt', methods=['POST']) @verify_session( # We add the UserRoleClaim's includes validator override_global_claim_validators=lambda global_validators, session, user_context: global_validators + \ [UserRoleClaim.validators.includes("admin")])def like_comment(): # All validator checks have passed and the user has a verified email address pass
from supertokens_python.recipe.session.framework.django.asyncio import verify_sessionfrom django.http import HttpRequestfrom supertokens_python.recipe.userroles import UserRoleClaim
@verify_session( # We add the UserRoleClaim's includes validator override_global_claim_validators=lambda global_validators, session, user_context: global_validators + \ [UserRoleClaim.validators.includes("admin")])async def like_comment(request: HttpRequest): # All validator checks have passed and the user has a verified email address pass
- We add the
UserRoleClaim
validator to theverifySession
function which makes sure that the user has anadmin
role. - The
globalValidators
represents other validators that apply to all API routes by default. This may include a validator that enforces that the user's email is verified (if enabled by you). - We can also add a
PermissionClaim
validator to enforce a permission.
feature
You can also build your own custom claim validators based on your app's requirements.