You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

65 lines
2.0 KiB

export type CookieOptions = {
path?: string
domain?: string
expires?: Date | string | number
maxAge?: number
secure?: boolean
httpOnly?: boolean
sameSite?: 'lax' | 'strict' | 'none'
}
export function serializeCookie(name: string, value: string, options: CookieOptions = {}): string {
const enc = encodeURIComponent
let cookie = `${name}=${enc(value)}`
if (options.maxAge != null) cookie += `; Max-Age=${Math.floor(options.maxAge)}`
if (options.expires != null) {
const date = typeof options.expires === 'number' ? new Date(options.expires) : new Date(options.expires)
cookie += `; Expires=${date.toUTCString()}`
}
if (options.domain) cookie += `; Domain=${options.domain}`
if (options.path) cookie += `; Path=${options.path}`
if (options.secure) cookie += `; Secure`
if (options.httpOnly) cookie += `; HttpOnly`
if (options.sameSite) cookie += `; SameSite=${options.sameSite === 'none' ? 'None' : options.sameSite === 'lax' ? 'Lax' : 'Strict'}`
return cookie
}
export function parseCookieHeader(header: string | undefined): Record<string, string> {
const raw = header || ''
const out: Record<string, string> = {}
raw.split(';').map(s => s.trim()).filter(Boolean).forEach(kv => {
const idx = kv.indexOf('=')
const k = idx >= 0 ? kv.slice(0, idx) : kv
const v = idx >= 0 ? decodeURIComponent(kv.slice(idx + 1)) : ''
out[k] = v
})
return out
}
export function parseDocumentCookies(): Record<string, string> {
if (typeof document === 'undefined') return {}
return parseCookieHeader(document.cookie)
}
/**
// server 侧中间件
import { parseCookieHeader, serializeCookie } from './src/compose/cookieUtils'
app.use(async (ctx, next) => {
const cookies = parseCookieHeader(ctx.request.headers.cookie as string)
// 读取
const token = cookies['demo_token']
// 写入(HttpOnly 更安全)
if (!token) {
const setItem = serializeCookie('demo_token', 'from-mw', {
httpOnly: true, path: '/', sameSite: 'lax'
})
ctx.set('Set-Cookie', [setItem])
}
await next()
})
*/