Creating a new session
#
How to create a new sessionCreate a new session after verifying user's credentials in the login API, or after creating a new user in the sign up API.
- NodeJS
- GoLang
- Python
- Other Frameworks
Important
- Express
- Hapi
- Fastify
- Koa
- Loopback
- AWS Lambda / Netlify
- Next.js
- NestJS
import express from "express";
import Session from "supertokens-node/recipe/session";
import supertokens from "supertokens-node";
let app = express();
app.post("/login", async (req, res) => {
// verify user's credentials...
let userId = "userId"; // get from db
await Session.createNewSession(req, res, "public", supertokens.convertToRecipeUserId(userId));
/* a new session has been created.
* - an access & refresh token has been attached to the response's cookie
* - a new row has been inserted into the database for this new session
*/
res.json({ message: "User logged in!" });
})
import Hapi from "@hapi/hapi";
import Session from "supertokens-node/recipe/session";
import supertokens from "supertokens-node";
let server = Hapi.server({ port: 8000 });
server.route({
path: "/login",
method: "post",
handler: async (req, res) => {
// verify user's credentials...
let userId = "userId"; // get from db
await Session.createNewSession(req, res, "public", supertokens.convertToRecipeUserId(userId));
/* a new session has been created.
* - an access & refresh token has been attached to the response's cookie
* - a new row has been inserted into the database for this new session
*/
return res.response({ message: "User logged in!" }).code(200);
},
});
import Fastify from "fastify";
import Session from "supertokens-node/recipe/session";
import supertokens from "supertokens-node";
let fastify = Fastify();
fastify.post("/login", async (req, res) => {
// verify user's credentials...
let userId = "userId"; // get from db
await Session.createNewSession(req, res, "public", supertokens.convertToRecipeUserId(userId));
/* a new session has been created.
* - an access & refresh token has been attached to the response's cookie
* - a new row has been inserted into the database for this new session
*/
res.send({ message: "User logged in!" });
})
import { middleware } from "supertokens-node/framework/awsLambda"
import Session from "supertokens-node/recipe/session";
import { SessionEvent } from "supertokens-node/framework/awsLambda";
import supertokens from "supertokens-node";
async function login(awsEvent: SessionEvent) {
// verify user's credentials...
let userId = "userId"; // get from db
await Session.createNewSession(awsEvent, awsEvent, "public", supertokens.convertToRecipeUserId(userId));
/* a new session has been created.
* - an access & refresh token has been attached to the response's cookie
* - a new row has been inserted into the database for this new session
*/
return {
body: JSON.stringify({ message: "User logged in!" }),
statusCode: 200,
};
}
exports.handler = middleware(login);
import KoaRouter from "koa-router";
import Session from "supertokens-node/recipe/session";
import supertokens from "supertokens-node";
let router = new KoaRouter();
router.post("/login", async (ctx, next) => {
// verify user's credentials...
let userId = "userId"; // get from db
await Session.createNewSession(ctx, ctx, "public", supertokens.convertToRecipeUserId(userId));
/* a new session has been created.
* - an access & refresh token has been attached to the response's cookie
* - a new row has been inserted into the database for this new session
*/
ctx.body = { message: "User logged in!" };
})
import { inject } from "@loopback/core";
import { RestBindings, MiddlewareContext, post, response } from "@loopback/rest";
import Session from "supertokens-node/recipe/session";
import supertokens from "supertokens-node";
class Login {
constructor(@inject(RestBindings.Http.CONTEXT) private ctx: MiddlewareContext) { }
@post("/login")
@response(200)
async handler() {
// verify user's credentials...
let userId = "userId"; // get from db
await Session.createNewSession(this.ctx, this.ctx, "public", supertokens.convertToRecipeUserId(userId));
return { message: "User logged in!" };
}
}
import { superTokensNextWrapper } from 'supertokens-node/nextjs'
import { createNewSession } from "supertokens-node/recipe/session";
import { SessionRequest } from "supertokens-node/framework/express";
import supertokens from "supertokens-node";
export default async function superTokens(req: SessionRequest, res: any) {
// verify user's credentials...
let userId = "userId"; // get from db
await superTokensNextWrapper(
async (next) => {
await createNewSession(req, res, "public", supertokens.convertToRecipeUserId(userId));
},
req,
res
);
res.json({
message: "User logged in!"
});
}
import { Controller, Post, Res, Req } from "@nestjs/common";
import type { Response, Request } from "express";
import { createNewSession } from "supertokens-node/recipe/session";
import supertokens from "supertokens-node";
@Controller()
export class ExampleController {
// For more information about "AuthGuard" and the "Session" decorator please read our NestJS guide.
@Post("login")
async postLogin(@Req() req: Request, @Res() res: Response): Promise<{ message: string }> {
let userId = "userId"; // get from db
await createNewSession(req, res, "public", supertokens.convertToRecipeUserId(userId));
/* a new session has been created.
* - an access & refresh token has been attached to the response's cookie
* - a new row has been inserted into the database for this new session
*/
return { message: "User logged in!" };
}
}
import (
"net/http"
"github.com/supertokens/supertokens-golang/recipe/session"
"github.com/supertokens/supertokens-golang/supertokens"
)
func login(w http.ResponseWriter, r *http.Request) {
// verify user's credentials...
userId := "userId" // get from db
tenantId := "public"
_, err := session.CreateNewSession(r, w, tenantId, userId, nil, nil)
if err != nil {
err = supertokens.ErrorHandler(err, r, w)
if err != nil {
// Send 500 to client
}
}
/* a new session has been created.
* - an access & refresh token has been attached to the response's cookie
* - a new row has been inserted into the database for this new session
*/
// Send 200 success to client
}
- FastAPI
- Flask
- Django
from supertokens_python.recipe.session.asyncio import create_new_session
from fastapi import Request
from fastapi.responses import JSONResponse
@app.post('/login')
async def login(request: Request):
# verify user's credentials...
user_id = "..." # get from db
await create_new_session(request, "public", user_id)
# a new session has been created.
# - an access & refresh token has been attached to the response's cookie
# - a new row has been inserted into the database for this new session
#
return JSONResponse({"message": "User logged in!"})
from supertokens_python.recipe.session.syncio import create_new_session
from flask import jsonify
from flask.wrappers import Request
@app.route('/login', methods=['POST'])
def login(request: Request):
# verify user's credentials...
user_id = "..." # get from db
create_new_session(request, "public", user_id)
# a new session has been created.
# - an access & refresh token has been attached to the response's cookie
# - a new row has been inserted into the database for this new session
#
return jsonify({"message": "User logged in!"})
from supertokens_python.recipe.session.asyncio import create_new_session
from django.http import HttpRequest, JsonResponse
async def login(request: HttpRequest):
# verify user's credentials...
user_id = "..." # get from db
await create_new_session(request, "public", user_id)
# a new session has been created.
# - an access & refresh token has been attached to the response's cookie
# - a new row has been inserted into the database for this new session
#
return JsonResponse({"message": "User logged in!"})
Multi Tenancy
Notice that we pass in the "public"
tenantId to the function call above. This is the default tenantId in SuperTokens. The session will be created for that passed in tenantId, and the tId
claim in the access token payload will have this value.
#
CreateNewSession without req / res dependencyIn the above version of the createNewSession
function, we pass it the request
object and the response
object (depending on the language and framework). Whilst this is convenient, you may want to create a new session without using the req
and res
objects and take control of how the tokens are set in the response. This is possible by using the createNewSessionWithoutRequestResponse
function.
- NodeJS
- GoLang
- Python
- Other Frameworks
Important
import express from "express";
import Session from "supertokens-node/recipe/session";
import supertokens from "supertokens-node";
let app = express();
app.post("/login", async (req, res) => {
// verify user's credentials...
let userId = "userId"; // get from db
let session = await Session.createNewSessionWithoutRequestResponse("public", supertokens.convertToRecipeUserId(userId));
// we can fetch the session tokens from the session object as follows:
const tokens = session.getAllSessionTokensDangerously();
if (tokens.accessAndFrontTokenUpdated) {
// TODO: set access token in response via tokens.accessToken
// TODO: set front-token in response via tokens.frontToken
if (tokens.refreshToken) {
// TODO: set refresh token update in response via tokens.refreshToken
}
if (tokens.antiCsrfToken) {
// TODO: set anti-csrf token update in response via tokens.antiCsrfToken
}
}
res.json({ message: "User logged in!" });
})
import (
"net/http"
"github.com/supertokens/supertokens-golang/recipe/session"
"github.com/supertokens/supertokens-golang/supertokens"
)
func login(w http.ResponseWriter, r *http.Request) {
// verify user's credentials...
userId := "userId" // get from db
tenantId := "public"
session, err := session.CreateNewSessionWithoutRequestResponse(tenantId, userId, nil, nil, nil)
if err != nil {
err = supertokens.ErrorHandler(err, r, w)
if err != nil {
// Send 500 to client
}
}
tokens := session.GetAllSessionTokensDangerously()
if (tokens.AccessAndFrontendTokenUpdated) {
// TODO: set access token in response via tokens.AccessToken
// TODO: set front-token in response via tokens.FrontToken
if (tokens.RefreshToken != nil) {
// TODO: set refresh token update in response via *tokens.RefreshToken
}
if (tokens.AntiCsrfToken != nil) {
// TODO: set anti-csrf token update in response via *tokens.AntiCsrfToken
}
}
// Send 200 success to client
}
from supertokens_python.recipe.session.asyncio import create_new_session_without_request_response
from fastapi import Request
from fastapi.responses import JSONResponse
@app.post('/login')
async def login(request: Request):
# verify user's credentials...
user_id = "..." # get from db
session = await create_new_session_without_request_response("public", user_id)
tokens = session.get_all_session_tokens_dangerously()
if tokens["accessAndFrontTokenUpdated"]:
# TODO: set access token in response via tokens["accessToken"]
# TODO: set front-token in response via tokens["frontToken"]
if tokens["refreshToken"] is not None:
# TODO: set refresh token in response via tokens["refreshToken"]
pass
if tokens["antiCsrfToken"] is not None:
# TODO: set anti-csrf token update in response via tokens["antiCsrfToken"]
pass
return JSONResponse({"message": "User logged in!"})
Multi Tenancy
Notice that we pass in the "public"
tenantId to the function call above. This is the default tenantId in SuperTokens. The session will be created for that passed in tenantId, and the tId
claim in the access token payload will have this value.