🚀Announcing Flightcontrol - Easily Deploy Blitz.js and Next.js to AWS 🚀
Back to Documentation Menu

Auth Server-Side APIs

Topics

Jump to a Topic

In Queries & Mutations

SessionContext is available off of ctx which is provided as the second parameter to all queries and mutations.

// src/queries/someQuery.ts
import { Ctx } from "blitz"

export default async function someQuery(input: any, ctx: Ctx) {
  // Access the SessionContext class
  ctx.session.userId
  ctx.session.role
  ctx.session.$create(/*...*/)

  return
}

getServerSideProps

You can get the session context inside getServerSideProps by wrapping it with the gSSP function exported from src/blitz-server:

import { SessionContext } from "@blitzjs/auth"
import { gSSP } from "src/blitz-server"

type Props = {
  userId: unknown
  publicData: SessionContext["$publicData"]
}

export const getServerSideProps = gSSP<Props>(async ({ ctx }) => {
  const { session } = ctx
  return {
    props: {
      userId: session.userId,
      publicData: session.$publicData,
      publishedAt: new Date(0),
    },
  }
})

function PageWithGssp(props: Props) {
  return <div>{JSON.stringify(props, null, 2)}</div>
}

export default PageWithGssp

App Router API Routes

You can get the session context inside API routes by wrapping it with the withBlitzAuth function exported from src/blitz-server:

//app/api/logout/route.ts
import { withBlitzAuth } from "app/blitz-server"

export const POST = withBlitzAuth(async (_request, _params, ctx) => {
  const session = ctx.session
  await session.$revoke()
  return new Response(
    JSON.stringify({
      userId: session.userId,
    }),
    { status: 200 }
  )
})

withBlitzAuth API

The function supports both single handler as an input as well as an object of handlers and has the following signature:

function withBlitzAuth(handlers: { [method: string]: Handler })
Arguments
  • handlers: { [method: string]: Handler }) - An object of handlers where the key is the HTTP method and the value is the handler function.
type Handler = (
  request: Request,
  params: Record<string, string>,
  ctx: { session: SessionContext }
) => Promise<Response>
Returns
  • { [method: string]: Handler } - The wrapper function returns an object of handlers where the key is the HTTP method and the value is the handler function wrapped with the session management of @blitzjs/auth.

    Example Usage with single handler
//app/api/logout/route.ts
import { withBlitzAuth } from "app/blitz-server"

export const { POST } = withBlitzAuth({
  POST: async (_request, _params, { session }) => {
    // logout the user
    await session.$revoke()
    return new Response(
      JSON.stringify({
        userId: session.userId,
      }),
      { status: 200 }
    )
  },
})
Example Usage with multiple handlers
//app/api/multiple/route.ts
import { withBlitzAuth } from "app/blitz-server"

export const { GET, POST } = withBlitzAuth({
  GET: async (_request, _params, { session }) => {
    return new Response(
      JSON.stringify({
        userId: session.userId,
      }),
      { status: 200 }
    )
  },
  POST: async (_request, _params, { session }) => {
    return new Response(
      JSON.stringify({
        userId: session.userId,
      }),
      { status: 200 }
    )
  },
})

Pages Router API Routes

You can get the session context inside API routes by wrapping it with the api function exported from src/blitz-server:

import { api } from "src/blitz-server"
import db from "db"

export default api(async (_req, res, ctx) => {
  ctx.session.$authorize()
  const publicData = ctx.session.$publicData

  res.status(200).json({
    userId: ctx.session.userId,
    publicData: { ...publicData },
  })
})

generateToken()

generateToken(numberOfCharacters: number = 32) => string

This is a convenience wrapper around nanoid for generating tokens for things like password resets.

Example Usage

import { generateToken } from "@blitzjs/auth"

const token = generateToken()

hash256()

hash256(value: string) => string

This is a convenience wrapper that uses the node crypto module to hash a string with the sha256 algorithm. It is used for things like hashing password reset tokens before saving them in the database.

Hash256 is also useful for storing strings like API keys in the database because the returned hash will always be the same for a given string. Therefore, you can still verify that an API key exists in the database when the only value you have to reference is the hashed key.

Example Usage

import { hash256 } from "@blitzjs/auth"

const hashedToken = hash256(token)

SecurePassword

SecurePassword is a convenience wrapper around secure-password to provide a nice way to hash passwords and verify password hashes.

import { SecurePassword } from "@blitzjs/auth"

await SecurePassword.hash(password)
await SecurePassword.verify(passwordHash, password)

SecurePassword.hash(password: string) => Promise<string>

This is used when a user sets a new password.

It takes a password string and returns a secure hash for storing in your database.

SecurePassword.hash will return a different hash when given the same string, hence the necessity of SecurePassword.verify to compare hashes.

SecurePassword.verify(passwordHash: string, password: string) => Promise<ResultCode>

This is used when a user logs in to verify they used the correct password.

It takes a password hash from your database and the given password. It will verify the given password is correct and return a result code, or if incorrect, it will throw AuthenticationError.

Result Codes

SecurePassword.VALID

The password was verified and is valid

SecurePassword.VALID_NEEDS_REHASH

The password was verified and is valid, but needs to be rehashed with new parameters

SecurePassword.HASH_BYTES

Size of the hash Buffer returned by hash and hashSync and used by verify and verifySync.

Example Usage

import { AuthenticationError } from "blitz"
import { SecurePassword } from "@blitzjs/auth"
import db from "db"

export const authenticateUser = async (
  email: string,
  password: string
) => {
  const user = await db.user.findFirst({ where: { email } })
  if (!user) throw new AuthenticationError()

  const result = await SecurePassword.verify(
    user.hashedPassword,
    password
  )

  if (result === SecurePassword.VALID_NEEDS_REHASH) {
    // Upgrade hashed password with a more secure hash
    const improvedHash = await SecurePassword.hash(password)
    await db.user.update({
      where: { id: user.id },
      data: { hashedPassword: improvedHash },
    })
  }

  const { hashedPassword, ...rest } = user
  return rest
}

setPublicDataForUser()

setPublicDataForUser(userId: PublicData['userId'], publicData: Record<any, any>) => void

This can be used to update the publicData of a user's sessions. It can be useful when changing a user's role, since the new permissions can be enforced as soon as the user is doing the next request.

Example Usage

import { setPublicDataForUser } from "@blitzjs/auth"
import db from "db"

export const updateUserRole = async (
  userId: PublicData["userId"],
  role: string
) => {
  // update the user's role
  await db.user.update({ where: { id: userId }, data: { role } })
  // update role in all active sessions
  await setPublicDataForUser(userId, { role })
}
Note

The following methods are meant for internal usage or for advanced use cases. They are not needed for general use.

getSession

This function is used internally by Blitz to get the session context from the request either from an IncomingMessage and ServerResponse pair or from a Request object.

Arguments

  • req: IncomingMessage | Request - The request object from the server.
  • res: ServerResponse | never - The response object from the server.
  • isRsc: boolean - A boolean that determines if the request is for a resource.

Returns

  • SessionContext - The session context object.

SessionContext.setSession

This function is used along with getSession to set the session context on the response object after the session has been created or updated.

Arguments

  • response: Response | ServerResponse - The response object from the server.

Returns

  • void

Example Usage

With Request
async function handler(request: Request, params: Record<string, string>) {
  const session = await getSession(request)
  const response = await handler(request, params, { session })
  session.setSession(response)
  return response
}
With IncomingMessage and ServerResponse
async function handler(req: IncomingMessage, res: ServerResponse) {
  const session = await getSession(req, res)
  await handler(req, res, { session })
  session.setSession(res)
}
  • handler is a function that processes the request and can mutate the session state
  • The response | res will contain the session state after the handler has been processed

Idea for improving this page? Edit it on GitHub.