Skip to content

Instantly share code, notes, and snippets.

@daaru00
Created February 22, 2024 11:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save daaru00/faef5b3b243a470c2eab15a4e3deff9d to your computer and use it in GitHub Desktop.
Save daaru00/faef5b3b243a470c2eab15a4e3deff9d to your computer and use it in GitHub Desktop.
Session management using encrypted server-only cookie
import crypto from 'crypto'
const COOKIE_NAME = 'session'
const COOKIE_GET_HEADER = 'Cookie'
const COOKIE_SET_HEADER = 'Set-Cookie'
const ENCRYPTION_ALGORITHM = 'aes-256-cbc'
/**
* Decode session from cookie header
*
* @param {object} headers
* @param {string} key
* @returns {object|null} session
*/
export function decodeSession(headers = {}, key) {
const cookieHeader = headers[COOKIE_GET_HEADER] || headers[COOKIE_GET_HEADER.toLowerCase()]
if (!cookieHeader) {
return null
}
const cookies = cookieHeader.split(';').map(v => v.trim()).reduce((acc, cookie) => {
const [key, value] = cookie.split('=')
acc[key] = value
return acc
}, {})
if (!cookies[COOKIE_NAME]) {
return null
}
const value = decodeURIComponent(cookies[COOKIE_NAME])
const [iv, data] = value.split(':').map(value => Buffer.from(value, 'hex'))
let decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(key), iv)
let decrypted = decipher.update(data)
decrypted = Buffer.concat([decrypted, decipher.final()])
return JSON.parse(decrypted.toString())
}
/**
* Encode session into cookie header
*
* @param {object} data
* @param {string} key
* @returns {object} headers
*/
export function encodeSession(data = {}, key) {
const iv = crypto.randomBytes(16)
const cipher = crypto.createCipheriv(ENCRYPTION_ALGORITHM, Buffer.from(key), iv)
let encrypted = cipher.update(JSON.stringify(data))
encrypted = Buffer.concat([encrypted, cipher.final()])
const value = iv.toString('hex') + ':' + encrypted.toString('hex')
return {
[COOKIE_SET_HEADER]: `${COOKIE_NAME}=${encodeURIComponent(value)}; Secure; HttpOnly`
}
}
/**
* Clean session
*
* @returns {object} headers
*/
export function cleanSession() {
return {
[COOKIE_SET_HEADER]: `${COOKIE_NAME}=none; Max-Age=1`
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment