Lucia Auth Cheat Sheet
Quick reference for Lucia authentication: session management, password hashing, OAuth integration, CSRF protection, and middleware setup for modern JavaScript frameworks.
Setup
| npm install lucia | Install the Lucia auth library |
| npm install @lucia-auth/adapter-drizzle | Install the Drizzle ORM adapter |
| npm install @lucia-auth/adapter-prisma | Install the Prisma adapter |
| import { Lucia } from "lucia" | Import the main Lucia class |
| const lucia = new Lucia(adapter, { sessionCookie: { attributes: { secure: true } } }) | Initialize Lucia with an adapter and secure cookies |
| const lucia = new Lucia(adapter, { getUserAttributes: (attrs) => ({ email: attrs.email }) }) | Expose custom user attributes from the database |
| npm install @lucia-auth/adapter-sqlite | Install the SQLite adapter for Lucia |
| npm install arctic | Install Arctic for OAuth provider helpers |
Session Management
| const session = await lucia.createSession(userId, {}) | Create a new session for a user |
| const sessionCookie = lucia.createSessionCookie(session.id) | Create a cookie from a session ID |
| const blankCookie = lucia.createBlankSessionCookie() | Create a blank cookie to clear the session |
| const { session, user } = await lucia.validateSession(sessionId) | Validate a session and get user data |
| await lucia.invalidateSession(sessionId) | Invalidate (delete) a specific session |
| await lucia.invalidateUserSessions(userId) | Invalidate all sessions for a user |
| await lucia.deleteExpiredSessions() | Remove all expired sessions from storage |
| setCookie(sessionCookie.name, sessionCookie.value, sessionCookie.attributes) | Set the session cookie in the response |
Password Auth
| import { Scrypt } from "lucia" | Import the Scrypt password hasher |
| const hashedPassword = await new Scrypt().hash(password) | Hash a password with Scrypt |
| const isValid = await new Scrypt().verify(hashedPassword, password) | Verify a password against a hash |
| import { generateId } from "lucia" | Import the ID generator utility |
| const userId = generateId(15) | Generate a random 15-character user ID |
| import { Argon2id } from "lucia" | Import the Argon2id password hasher (recommended) |
| const hash = await new Argon2id().hash(password) | Hash a password with Argon2id |
| const valid = await new Argon2id().verify(hash, password) | Verify a password with Argon2id |
OAuth
| import { GitHub } from "arctic" | Import the GitHub OAuth provider from Arctic |
| const github = new GitHub(clientId, clientSecret) | Create a GitHub OAuth client |
| const url = await github.createAuthorizationURL(state, { scopes: ["user:email"] }) | Generate the OAuth authorization URL |
| const tokens = await github.validateAuthorizationCode(code) | Exchange the authorization code for tokens |
| import { Google } from "arctic" | Import the Google OAuth provider |
| const google = new Google(clientId, clientSecret, redirectURI) | Create a Google OAuth client |
| const url = await google.createAuthorizationURL(state, codeVerifier, { scopes: ["email"] }) | Generate Google OAuth URL with PKCE |
| import { generateState, generateCodeVerifier } from "arctic" | Import OAuth state and PKCE helpers |
Middleware
| const sessionId = cookies.get(lucia.sessionCookieName)?.value ?? null | Read the session ID from cookies |
| if (!session) return new Response(null, { status: 401 }) | Return 401 if no valid session exists |
| if (session?.fresh) setCookie(lucia.createSessionCookie(session.id)) | Refresh the cookie if the session was extended |
| const { session, user } = await lucia.validateSession(sessionId) | Validate session in middleware and extract user |
| event.locals.user = user | Attach user to request locals (SvelteKit example) |
| c.set("user", user) | Attach user to Hono context |
| request.user = user | Attach user to Express request object |
Security
| sessionCookie: { attributes: { secure: true, sameSite: "lax" } } | Configure secure cookie attributes |
| import { verifyRequestOrigin } from "lucia" | Import CSRF origin verification helper |
| verifyRequestOrigin(originHeader, [host]) | Verify the request origin matches the host |
| if (request.method !== "GET") verifyRequestOrigin(origin, [host]) | Apply CSRF check to non-GET requests |
| sessionCookie: { expires: false } | Create a session cookie that persists until browser close |
| sessionExpiresIn: new TimeSpan(30, "d") | Set session expiration to 30 days |
| const { session } = await lucia.validateSession(id); if (!session) redirect("/login") | Protect a route by validating the session |
| await lucia.invalidateUserSessions(userId) | Force logout from all devices by invalidating all sessions |
Try It Live
Test these patterns with our free API Tester. No signup needed.
Open API Tester →
Step-by-Step Guide
Read Guide →