~4 دقیقه مطالعه • بروزرسانی ۴ آبان ۱۴۰۴
مقدمه
مدیریت نشست به حفظ وضعیت ورود کاربر در طول تعامل با اپلیکیشن کمک میکند. دو نوع نشست وجود دارد:
- نشست بدونوضعیت: دادهٔ نشست در کوکی مرورگر ذخیره میشود و در هر درخواست ارسال میگردد.
- نشست پایگاهداده: دادهٔ نشست در دیتابیس ذخیره میشود و مرورگر فقط شناسهٔ رمزنگاریشده را دریافت میکند.
برای سادگی و امنیت بیشتر، استفاده از کتابخانههایی مانند iron-session یا Jose توصیه میشود.
نشست بدونوضعیت با رمزنگاری JWT
۱. تولید کلید مخفی
در ترمینال:
openssl rand -base64 32و در فایل .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: '/',
})
}۴. ایجاد نشست در Server Action
// app/actions/auth.ts
import { createSession } from '@/app/lib/session'
export async function signup(_, formData) {
// اعتبارسنجی و درج کاربر
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')
}و در اکشن خروج:
export async function logout() {
await deleteSession()
redirect('/login')
}نشست پایگاهداده
برای نشست پایگاهداده:
// 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: '/',
})
}نکات امنیتی و عملکردی
- از رمزنگاری برای جلوگیری از دستکاری نشست استفاده کنید
- اطلاعات حساس مانند ایمیل یا رمز عبور را در payload ذخیره نکنید
- برای نشستهای پایگاهداده، میتوانید زمان آخرین ورود یا دستگاههای فعال را پیگیری کنید
- پس از پیادهسازی نشست، منطق مجوزدهی (Authorization) را اضافه کنید
جمعبندی
مدیریت نشست در Next.js با استفاده از کوکیهای امن یا پایگاهداده قابل پیادهسازی است. با رمزنگاری، تنظیمات دقیق کوکی، و حذف امن، میتوان تجربهای امن و پایدار برای کاربران فراهم کرد.
نوشته و پژوهش شده توسط دکتر شاهین صیامی