Implement signed cookie helpers
Provide a convenient wrapper for setting SHA-256 HMAC signed cookies and retreiving them with the signature validated. The secret key is configured in the NUXT_COOKIE_SECRET_KEY environment variable.
This commit is contained in:
parent
5044b7b58d
commit
8da4b02154
4 changed files with 60 additions and 10 deletions
42
server/utils/signed-cookie.ts
Normal file
42
server/utils/signed-cookie.ts
Normal file
|
@ -0,0 +1,42 @@
|
|||
import type { H3Event } from "h3";
|
||||
|
||||
let cachedCookieSecret: CryptoKey;
|
||||
export async function useCookieSecret(event: H3Event) {
|
||||
if (cachedCookieSecret)
|
||||
return cachedCookieSecret;
|
||||
|
||||
const runtimeConfig = useRuntimeConfig(event);
|
||||
return cachedCookieSecret = await crypto.subtle.importKey(
|
||||
"raw",
|
||||
Buffer.from(runtimeConfig.cookieSecretKey, "base64url"),
|
||||
{ name: "HMAC", hash: "SHA-256" },
|
||||
false,
|
||||
["sign", "verify"],
|
||||
);
|
||||
}
|
||||
|
||||
export async function setSignedCookie(event: H3Event, name: string, value: string) {
|
||||
const secret = await useCookieSecret(event);
|
||||
const signature = await crypto.subtle.sign("HMAC", secret, Buffer.from(value));
|
||||
const cookie = `${value}.${Buffer.from(signature).toString("base64url")}`
|
||||
setCookie(event, name, cookie, { httpOnly: true, secure: true, sameSite: true });
|
||||
}
|
||||
|
||||
export async function getSignedCookie(event: H3Event, name: string) {
|
||||
const cookie = getCookie(event, name);
|
||||
if (!cookie)
|
||||
return;
|
||||
|
||||
const rightDot = cookie.lastIndexOf(".");
|
||||
if (rightDot === -1)
|
||||
return;
|
||||
|
||||
const value = cookie.slice(0, rightDot);
|
||||
const secret = await useCookieSecret(event);
|
||||
const signature = Buffer.from(cookie.slice(rightDot + 1), "base64url");
|
||||
const valid = await crypto.subtle.verify("HMAC", secret, signature, Buffer.from(value));
|
||||
if (!valid)
|
||||
return
|
||||
|
||||
return value;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue