Skip to content

Session Authentication

Session-based auth stores state on the server and identifies requests via a signed cookie. Velox TS sessions include HMAC-SHA256 signing, sliding expiration, flash messages, and session regeneration on login to prevent fixation attacks.

import { sessionMiddleware, inMemorySessionStore } from '@veloxts/auth';
const session = sessionMiddleware({
secret: process.env.SESSION_SECRET!,
store: inMemorySessionStore(), // Use Redis in production
cookie: {
name: 'session',
secure: true,
httpOnly: true,
sameSite: 'lax',
maxAge: 86400, // 24 hours
},
});
login: procedure()
.use(session.optional())
.input(LoginSchema)
.mutation(async ({ input, ctx }) => {
const user = await verifyCredentials(input);
// Create session (regenerates session ID to prevent fixation)
await ctx.session.login({
id: user.id,
email: user.email,
});
return { user };
}),
logout: procedure()
.use(session.required())
.mutation(async ({ ctx }) => {
await ctx.session.logout();
return { success: true };
}),
getProfile: procedure()
.use(session.required())
.query(({ ctx }) => ctx.user),
// Optional auth (user may or may not be logged in)
homePage: procedure()
.use(session.optional())
.query(({ ctx }) => ({ user: ctx.user ?? null })),
// Set flash message
ctx.session.flash('success', 'Profile updated!');
// Read flash message (one-time)
const message = ctx.session.getFlash('success');

For production, implement the SessionStore interface with Redis or another persistent store:

import type { SessionStore, StoredSession } from '@veloxts/auth';
import Redis from 'ioredis';
function createRedisStore(redis: Redis): SessionStore {
return {
async get(id: string): Promise<StoredSession | null> {
const data = await redis.get(`session:${id}`);
return data ? JSON.parse(data) : null;
},
async set(id: string, session: StoredSession, ttl: number): Promise<void> {
await redis.setex(`session:${id}`, ttl, JSON.stringify(session));
},
async destroy(id: string): Promise<void> {
await redis.del(`session:${id}`);
},
async touch(id: string, ttl: number): Promise<void> {
await redis.expire(`session:${id}`, ttl);
},
};
}
const session = sessionMiddleware({
store: createRedisStore(new Redis(process.env.REDIS_URL)),
// ...
});
  • JWT - Alternative approach
  • Guards - Authorization