passport-cookie-session
Version:
Encrypted, cookie-based session middleware compatible with PassportJS
156 lines (110 loc) • 5.7 kB
Markdown
# passport-cookie-session
[](https://www.npmjs.com/package/passport-cookie-session)
[](https://www.npmjs.com/package/passport-cookie-session)
A simple Express middleware to manage encrypted cookie sessions, **specially designed to work seamlessly with [PassportJS](https://www.passportjs.org) authentication**.
This package stores session data directly in an encrypted cookie, eliminating the need for a server-side session store.
---
## Table of Contents
- [Features](#features)
- [Installation](#installation)
- [Usage](#usage)
- [API](#api)
- [Security Notes](#security-notes)
- [License](#license)
---
## Features
- 🔐 AES-256-GCM encryption (or custom)
- 🔁 Key rotation support
- 🪪 **Built for PassportJS**
- 💡 Lightweight & stateless
---
## Installation
```bash
npm install passport-cookie-session
```
---
## Usage
```js
const express = require('express');
const passport = require('passport');
const passportCookieSession = require('passport-cookie-session');
const app = express();
app.use(passportCookieSession({
name: 'auth', // Optional. Default: 'session' — session cookie name
keys: ['super-secret-key', 'old-key'],
// Required. First key encrypts new cookies.
// Others are accepted for decrypting old cookies (key rotation support).
cookie: {
httpOnly: true, // Optional. Default: true — prevents JS access to cookie
secure: false, // Optional. Default: false — set true if using HTTPS
sameSite: 'lax', // Optional. Default: 'lax' — helps prevent CSRF
path: '/', // Optional. Default: '/' — cookie path scope
maxAge: 60 * 60, // Optional. Default: 86400 (1 day) — duration in seconds
// domain: 'example.com' // Optional. Default: current domain
},
maxCookieSize: 4096, // Optional. Default: 4096 bytes — max size, stay within browser limits
// 🔐 Custom async encryption/decryption functions (optional)
// Must return within the timeout or will throw.
// ⚠️ WARNING: Example uses insecure XOR cipher. Do NOT use in production!
encrypt: async function (data, signingKey) {
const secretChars = signingKey.split('').map(c => c.charCodeAt(0));
const textChars = data.split('').map(c => c.charCodeAt(0));
const encryptedChars = textChars.map((ch, i) => ch ^ secretChars[i % secretChars.length]);
return Buffer.from(encryptedChars).toString('base64');
},
decrypt: async function (data, signingKey) {
const secretChars = signingKey.split('').map(c => c.charCodeAt(0));
const encryptedChars = Buffer.from(data, 'base64');
const decryptedChars = [...encryptedChars].map((ch, i) => ch ^ secretChars[i % secretChars.length]);
return String.fromCharCode(...decryptedChars);
},
timeout: 3000, // Optional. Default: 3000ms — max allowed time for encrypt/decrypt
checkEncryption: true, // Optional. Default: false
// Runs a startup check of your custom encrypt/decrypt functions in non-production environments.
// Recommended during development to ensure your functions correctly round-trip data.
}));
app.use(passport.initialize());
app.use(passport.session());
// You must add and configure a Passport strategy for authentication, e.g.:
// passport.use(new LocalStrategy(...));
// Example serialization/deserialization
passport.serializeUser((user, done) => {
done(null, { id: user.id, username: user.username });
});
passport.deserializeUser((user, done) => done(null, user));
```
---
## API
### passport-cookie-session(options)
Creates Express middleware for encrypted cookie sessions.
Options:
- `name` (string) — Cookie name (default: `'session'`).
- `keys` (string[]) — Secret keys:
- First key is used to encrypt new cookies.
- Remaining keys are accepted for decrypting old cookies (key rotation).
- `cookie` (object) — Cookie options (see [cookie npm docs](https://github.com/jshttp/cookie#options-1)):
- `path` (default `'/'`)
- `httpOnly` (default `true`)
- `secure` (default `false`)
- `sameSite` (default `'lax'`)
- `maxAge` (seconds; default `86400`)
- `domain` (optional)
- `maxCookieSize` (number) — Maximum allowed cookie size in bytes (default: `4096`).
Keep within browser limits (typically 4096 bytes). Sessions exceeding this size will be rejected.
*Note:* Session size may vary with user data length, so plan accordingly.
- `encrypt(data, key)` (async function) — Optional custom encryption function.
- `decrypt(encrypted, key)` (async function) — Optional custom decryption function.
- `timeout` (number) — Optional timeout in milliseconds for encrypt/decrypt functions (default: `3000`).
- `checkEncryption` (boolean) — Optional (default: `false`).
Enables a startup check that runs your custom encrypt/decrypt functions to verify correct round-trip encryption.
Runs only in non-production environments. Strongly recommended during development if using custom functions.
---
## Security Notes
- Always use HTTPS in production and set secure: true.
- Rotate keys by adding new keys at the start of the keys array.
- Custom encrypt/decrypt should be cryptographically secure in real applications.
- Avoid storing large or sensitive data in the session cookie — keep payload minimal (e.g., user ID).
- Pay attention to the maxCookieSize to avoid cookie overflow and unexpected behavior.
---
## License
MIT © robodin08