Sign and verify stateless session tokens with jose in Next.js — create a signed JWT, set an expiry, and verify it on the server in both the Node and Edge runtimes.
Why: you create a token by signing your data with a secret only the server knows, and you trust an incoming token only if it verifies against that same secret. In Next.js the recommended library is jose — it runs in both the Node and Edge runtimes. Generate the secret once (openssl rand -base64 32) and keep it in an environment variable.
import { SignJWT, jwtVerify, type JWTPayload } from 'jose'
// SESSION_SECRET comes from: openssl rand -base64 32
const key = new TextEncoder().encode(process.env.SESSION_SECRET)
export async function sign(payload: JWTPayload) {
return new SignJWT(payload)
.setProtectedHeader({ alg: 'HS256' })
.setIssuedAt()
.setExpirationTime('7d') // the token stops being valid after 7 days
.sign(key)
}
export async function verify(token: string) {
const { payload } = await jwtVerify(token, key, { algorithms: ['HS256'] })
return payload // throws if the signature or the expiry is invalid
}