shared/lib/auth/jwt.ts

58 lines
1.7 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// shared/lib/auth/jwt.ts — 共享 JWT 签发/验证HS256跨站点 cookie
import crypto from 'crypto'
export interface SignJwtOptions {
secret: string
payload: Record<string, unknown>
expiresInSeconds?: number
}
export function signJwt({ secret, payload, expiresInSeconds = 604800 }: SignJwtOptions): string {
const header = { alg: 'HS256', typ: 'JWT' }
const now = Math.floor(Date.now() / 1000)
const body = { ...payload, iat: now, exp: now + expiresInSeconds }
const encoded = (obj: object) => Buffer.from(JSON.stringify(obj)).toString('base64url')
const signature = crypto
.createHmac('sha256', secret)
.update(`${encoded(header)}.${encoded(body)}`)
.digest('base64url')
return `${encoded(header)}.${encoded(body)}.${signature}`
}
export function verifyJwt(token: string, secret: string): Record<string, unknown> | null {
try {
const parts = token.split('.')
if (parts.length !== 3) return null
const payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString())
if (payload.exp && payload.exp * 1000 < Date.now()) return null
const signature = crypto
.createHmac('sha256', secret)
.update(`${parts[0]}.${parts[1]}`)
.digest('base64url')
return signature === parts[2] ? payload : null
} catch {
return null
}
}
// 签发共享 tlyq_session cookie 配置
export function sharedCookieConfig(domain: string, maxAge = 604800): Record<string, unknown> {
return {
name: 'tlyq_session',
value: '',
options: {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax' as const,
domain,
path: '/',
maxAge,
},
}
}