Session management keeps users logged in across requests. There are two main approaches:
For simplicity and security, consider using libraries like iron-session or Jose.
Use the terminal:
openssl rand -base64 32Then store it in .env:
SESSION_SECRET=your_secret_key// app/lib/session.ts
import 'server-only'
import { SignJWT, jwtVerify } from 'jose'
const secretKey = process.env.SESSION_SECRET
const encodedKey = new TextEncoder().encode(secretKey)
export async function encrypt(payload) {
return new SignJWT(payload)
.setProtectedHeader({ alg: 'HS256' })
.setIssuedAt()
.setExpirationTime('7d')
.sign(encodedKey)
}
export async function decrypt(session = '') {
try {
const { payload } = await jwtVerify(session, encodedKey, {
algorithms: ['HS256'],
})
return payload
} catch {
console.log('Failed to verify session')
}
}// app/lib/session.ts
import { cookies } from 'next/headers'
export async function createSession(userId) {
const expiresAt = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)
const session = await encrypt({ userId, expiresAt })
const cookieStore = await cookies()
cookieStore.set('session', session, {
httpOnly: true,
secure: true,
expires: expiresAt,
sameSite: 'lax',
path: '/',
})
}// app/actions/auth.ts
import { createSession } from '@/app/lib/session'
export async function signup(_, formData) {
// Validate and insert user
await createSession(user.id)
redirect('/profile')
}export async function updateSession() {
const session = (await cookies()).get('session')?.value
const payload = await decrypt(session)
if (!session || !payload) return null
const expires = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)
const cookieStore = await cookies()
cookieStore.set('session', session, {
httpOnly: true,
secure: true,
expires,
sameSite: 'lax',
path: '/',
})
}export async function deleteSession() {
const cookieStore = await cookies()
cookieStore.delete('session')
}And in your logout action:
export async function logout() {
await deleteSession()
redirect('/login')
}To store sessions in a database:
// app/lib/session.ts
import { db } from '@/app/lib/db'
import { encrypt } from '@/app/lib/session'
export async function createSession(id) {
const expiresAt = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)
const data = await db.insert(sessions).values({ userId: id, expiresAt }).returning({ id: sessions.id })
const sessionId = data[0].id
const session = await encrypt({ sessionId, expiresAt })
const cookieStore = await cookies()
cookieStore.set('session', session, {
httpOnly: true,
secure: true,
expires: expiresAt,
sameSite: 'lax',
path: '/',
})
}Session management in Next.js can be implemented using secure cookies or database-backed strategies. With encryption, proper cookie settings, and safe deletion, you can deliver a secure and seamless user experience.