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
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()
|
|
})
|
|
*/
|