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
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.
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.
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
.
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
.
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.
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 })
}