Welcome to the Jose Madrid Salsa developer docs — explore features, APIs, and deployment guides.
Jose Madrid SalsaJMS Docs

JWT Configuration

JWT session strategy, token contents, and session management

JWT Configuration

Jose Madrid Salsa uses JWT (JSON Web Token) sessions exclusively -- there is no database session table. The JWT is signed with NEXTAUTH_SECRET and stored in an HTTP-only cookie.

Session Strategy

lib/auth.ts
session: {
  strategy: 'jwt',
  maxAge: 30 * 24 * 60 * 60, // 30 days
},
  • Strategy: jwt (no database adapter)
  • Max age: 30 days
  • Storage: HTTP-only, secure cookie in production

Token Contents

The JWT token is enriched in the jwt callback with application-specific fields:

FieldTypeSourceDescription
idstringDatabaseUser's CUID from the users table
emailstringNextAuthUser's email address
namestring?NextAuthUser's display name
roleUserRoleDatabaseOne of: CUSTOMER, ADMIN, DEVELOPER, STAFF, WHOLESALE, FUNDRAISER
fundraiserIdstring?DatabaseFundraiser ID if the user has role FUNDRAISER
avatarstring?OAuthProfile picture URL from Google/GitHub/Facebook

Session Object

The session callback maps token fields to session.user:

lib/auth.ts
async session({ session, token }) {
  if (session.user) {
    session.user.id = token.id
    session.user.role = token.role
    if (token.fundraiserId) session.user.fundraiserId = token.fundraiserId
    if (token.avatar) session.user.image = token.avatar
  }
  return session
}

Accessing the Session

Server-side (Server Components, API routes):

import { getServerSession } from 'next-auth'
import { authOptions } from '@/lib/auth'

const session = await getServerSession(authOptions)
const userId = session?.user?.id
const role = session?.user?.role

Client-side (Client Components):

import { useSession } from 'next-auth/react'

function MyComponent() {
  const { data: session } = useSession()
  const role = session?.user?.role
}
SettingDevelopmentProduction
useSecureCookiesfalsetrue
Cookie namenext-auth.session-token__Secure-next-auth.session-token
HttpOnlyYesYes
SameSiteLaxLax

Token Refresh Behavior

The JWT callback runs on every request that needs session data. The token enrichment follows this flow:

  1. Initial sign-in: User data (id, role) is added from the credentials provider or OAuth upsert
  2. Subsequent requests: Token already contains role; no database call needed
  3. Missing role fallback: If token.role is somehow missing, queries the database by email

This design minimizes database calls -- most requests use the cached role from the token.

Since the JWT contains the user's role, role changes in the database will not take effect until the user's current session expires or they sign out and back in.

Signing Secret

The JWT is signed with NEXTAUTH_SECRET:

secret: process.env.NEXTAUTH_SECRET,

Generate a strong secret:

openssl rand -base64 32

The NEXTAUTH_SECRET must be set in all environments. The application will throw an error in development if it is missing, and authentication will fail silently in production.

How is this guide?

Edit on GitHub

Last updated on

On this page