Revoking a session
#
Method 1: Revoking by creating your own API.important
We provide a default sign out API that does something very similar to the code below. So please have a look at that page first.
- 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("/logout", verifySession(), async (req: SessionRequest, res) => {
// This will delete the session from the db and from the frontend (cookies) await req.session!.revokeSession();
res.send("Success! User session revoked");});
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: "/logout", method: "post", options: { pre: [ { method: verifySession() }, ], }, handler: async (req: SessionRequest, res) => { // This will delete the session from the db and from the frontend (cookies) await req.session!.revokeSession(); return res.response("Success! User session revoked").code(200); }})
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("/logout", { preHandler: verifySession(),}, async (req: SessionRequest, res) => { // This will delete the session from the db and from the frontend (cookies) await req.session!.revokeSession();
res.send("Success! User session revoked");});
import { verifySession } from "supertokens-node/recipe/session/framework/awsLambda";import { SessionEvent } from "supertokens-node/framework/awsLambda";
async function logout(awsEvent: SessionEvent) { // This will delete the session from the db and from the frontend (cookies) await awsEvent.session!.revokeSession();
return { body: JSON.stringify({ message: "Success! User session revoked" }), statusCode: 200, };};
exports.handler = verifySession(logout);
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("/logout", verifySession(), async (ctx: SessionContext, next) => { // This will delete the session from the db and from the frontend (cookies) await ctx.session!.revokeSession();
ctx.body = "Success! User session revoked";});
import { inject, intercept } from "@loopback/core";import { RestBindings, post, response } from "@loopback/rest";import { verifySession } from "supertokens-node/recipe/session/framework/loopback";import { SessionContext } from "supertokens-node/framework/loopback";
class Logout { constructor(@inject(RestBindings.Http.CONTEXT) private ctx: SessionContext) { } @post("/logout") @intercept(verifySession()) @response(200) async handler() { // This will delete the session from the db and from the frontend (cookies) await this.ctx.session!.revokeSession();
return "Success! User session revoked"; }}
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 logout(req: SessionRequest, res: any) { await superTokensNextWrapper( async (next) => { await verifySession()(req, res, next); }, req, res ) // This will delete the session from the db and from the frontend (cookies) await req.session!.revokeSession(); res.send("Success! User session revoked");}
import { Controller, Post, UseGuards, Request, Response, Session } from "@nestjs/common";import { SessionContainer } from "supertokens-node/recipe/session";import { AuthGuard } from './auth/auth.guard';
@Controller()export class ExampleController { // For more information about "AuthGuard" and the "Session" decorator please read our NestJS guide. @Post('logout') @UseGuards(AuthGuard) async postLogout(@Session() session: SessionContainer): Promise<string> { await session.revokeSession();
return "Success! User session revoked"; }}
import ( "net/http"
"github.com/supertokens/supertokens-golang/recipe/session" "github.com/supertokens/supertokens-golang/supertokens")
func signoutAPI(w http.ResponseWriter, r *http.Request) { // retrieve the session object as shown below sessionContainer := session.GetSessionFromRequestContext(r.Context())
// This will delete the session from the db and from the frontend (cookies) err := sessionContainer.RevokeSession() if err != nil { err = supertokens.ErrorHandler(err, r, w) if err != nil { // TODO: Send 500 status code to client } return }
// TODO: Send 200 response to client}
- FastAPI
- Flask
- Django
from supertokens_python.recipe.session.framework.fastapi import verify_sessionfrom supertokens_python.recipe.session import SessionContainerfrom fastapi import Dependsfrom fastapi.responses import PlainTextResponse
async def logout(session: SessionContainer = Depends(verify_session())): await session.revoke_session() # This will delete the session from the db and from the frontend (cookies) return PlainTextResponse(content='success')
from supertokens_python.recipe.session.framework.flask import verify_sessionfrom supertokens_python.recipe.session import SessionContainerfrom flask import g
@app.route('/logout', methods=['POST']) @verify_session()def logout(): session: SessionContainer = g.supertokens
session.sync_revoke_session() # This will delete the session from the db and from the frontend (cookies) return 'success'
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 logout(request: HttpRequest): session: SessionContainer = request.supertokens This will delete the session from the db and from the frontend (cookies) await session.revoke_session()
tip
When calling this API from the frontend, please be sure to treat a 401
response as successful. The reason is that 401
means the session has expired, which is equivalent to a successful logout.
sessionHandle
.#
Method 2: Revoking a session using a caution
This and the remaining methods below will only delete the session from the db and not from the frontend.
This implies that the user will still be able to access protected endpoints while their access token is alive (unless you enable access token blacklisting).
- NodeJS
- GoLang
- Python
import express from "express";import Session from "supertokens-node/recipe/session";
let app = express();
app.use("/revoke-user-session", async (req, res) => {
let sessionHandle = req.body.sessionHandle
// sessionHandle is a string[] await Session.revokeSession(sessionHandle);
res.send("Success! User session revoked");});
import "github.com/supertokens/supertokens-golang/recipe/session"
func main() { sessionHandle := "someSessionHandle" revoked, err := session.RevokeSession(sessionHandle) if err != nil { // TODO: Handle error return }
if revoked { // session was revoked } else { // session was not found }}
- Asyncio
- Syncio
from supertokens_python.recipe.session.asyncio import revoke_session
async def some_func(): session_handle = "someSessionHandle" _ = await revoke_session(session_handle)
from supertokens_python.recipe.session.syncio import revoke_session
session_handle = "someSessionHandle"revoked = revoke_session(session_handle)
sessionHandle
.#
Method 3: Revoking multiple sessions using an array of - NodeJS
- GoLang
- Python
import express from "express";import Session from "supertokens-node/recipe/session";
let app = express();
app.use("/revoke-multiple-sessions", async (req, res) => {
let sessionHandles = req.body.sessionHandles await Session.revokeMultipleSessions(sessionHandles);
res.send("Success! All user sessions have been revoked");});
import ( "fmt"
"github.com/supertokens/supertokens-golang/recipe/session")
func main() { revokedSessionHandles, err := session.RevokeMultipleSessions([]string{ "sessionHandel1", "sessionHandle2", }) if err != nil { // TODO: Handle error return }
// revokedSessionHandles is an array of revoked session handles. fmt.Println(revokedSessionHandles)}
- Asyncio
- Syncio
from supertokens_python.recipe.session.asyncio import revoke_multiple_sessions
async def some_func(): session_handles = ["sessionHandel1", "sessionHandle2"] revoked_session_handles = await revoke_multiple_sessions(session_handles)
print(revoked_session_handles) # revoked_session_handles is an array of revoked session handles.
from supertokens_python.recipe.session.syncio import revoke_multiple_sessions
session_handles = ["sessionHandel1", "sessionHandle2"]revoked_session_handles = revoke_multiple_sessions(session_handles)
# revoked_session_handles is an array of revoked session handles.
userId
.#
Method 4: Revoking all sessions for a - NodeJS
- GoLang
- Python
import express from "express";import Session from "supertokens-node/recipe/session";
let app = express();
app.use("/revoke-all-user-sessions", async (req, res) => {
let userId = req.body.userId await Session.revokeAllSessionsForUser(userId);
res.send("Success! All user sessions have been revoked");});
import ( "fmt"
"github.com/supertokens/supertokens-golang/recipe/session")
func main() { revokedSessionHandles, err := session.RevokeAllSessionsForUser("userId") if err != nil { // TODO: Handle error return }
// revokedSessionHandles is an array of revoked session handles. fmt.Println(revokedSessionHandles)}
- Asyncio
- Syncio
from supertokens_python.recipe.session.asyncio import revoke_all_sessions_for_user
async def some_func(): user_id = "someUserId" revoked_session_handles = await revoke_all_sessions_for_user(user_id)
print(revoked_session_handles) # revoked_session_handles is an array of revoked session handles.
from supertokens_python.recipe.session.syncio import revoke_all_sessions_for_user
user_id = "someUserId"revoked_session_handles = revoke_all_sessions_for_user(user_id)
# revoked_session_handles is an array of revoked session handles.
#
Access token blacklistingOnce this feature is enabled, each session verification attempt will result in a database call. This will make sure that if session revocation has taken place, access tokens on the front end will be invalidated.
caution
On enabling this feature there will be a database call for each session verification attempt. This may slow down all of your API calls.
In the session revocation APIs defined in Method 2, Method 3 and Method 4, if the access token blacklisting feature is enabled, the access token which remains on the frontend does not matter as each session verification attempt will now require a database call.
You can enable this feature by setting the value in the core config:
- With Docker
- Without Docker
docker run \ -p 3567:3567 \ -e ACCESS_TOKEN_BLACKLISTING=true \ -d registry.supertokens.io/supertokens/supertokens-<db_name>
# You need to add the following to the config.yaml file.# The file path can be found by running the "supertokens --help" command
access_token_blacklisting: true
info
For managed service, this values can be updated by visiting our dashboard.