@fastify/session

Cookie-Based Sessions Without JWT

@fastify/session

The @fastify/session plugin stores session data server-side and references it through a signed cookie. Pair it with a Redis store for multi-instance apps.

4 min read Level 3/5 #fastify#session#auth
What you'll learn
  • Install @fastify/session alongside @fastify/cookie
  • Configure a secret and an optional Redis store
  • Read and write request.session

Sessions keep state on the server and hand the client only an opaque ID. Compared to JWTs, you can revoke instantly and store rich data — at the cost of a session store.

Install

npm install @fastify/cookie @fastify/session connect-redis ioredis

Register With Redis

import cookie from '@fastify/cookie'
import session from '@fastify/session'
import RedisStore from 'connect-redis'
import Redis from 'ioredis'

const redis = new Redis(app.config.REDIS_URL)
await app.register(cookie)
await app.register(session, {
  secret: app.config.SESSION_SECRET,
  store: new RedisStore({ client: redis, prefix: 'sess:' }),
  cookie: {
    secure: true,
    httpOnly: true,
    sameSite: 'lax',
    maxAge: 60 * 60 * 24 * 7 * 1000,
  },
})

The secret must be at least 32 characters. Without a store, sessions live in memory — fine for one process, fatal for clustered deployments.

Read & Write Session Data

declare module 'fastify' {
  interface Session {
    userId?: string
  }
}

app.post('/login', async (req, reply) => {
  // ... authenticate ...
  req.session.userId = 'user-123'
  return { ok: true }
})

app.post('/logout', async (req, reply) => {
  await req.session.destroy()
  return { ok: true }
})

The session cookie is signed automatically, so attackers cannot forge an ID. Rotate the secret periodically.

@fastify/passport →