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 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())
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_session
from supertokens_python.recipe.session import SessionContainer
from 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_session
from supertokens_python.recipe.session import SessionContainer
from 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_session
from django.http import HttpRequest
from 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 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())
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_session
from fastapi import Depends
from 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_session
from supertokens_python.recipe.session import SessionContainer
from typing import Union
from 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_session
from django.http import HttpRequest
from supertokens_python.recipe.session import SessionContainer
from 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 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 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_session
from supertokens_python.recipe.userroles import UserRoleClaim
from supertokens_python.recipe.session import SessionContainer
from 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_session
from 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_session
from django.http import HttpRequest
from 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.