JWT Configuration Across Subdomains
When using multiple applications hosted on subdomains (e.g., labs.example.com
and courses.example.com
), you can configure JWT-based sessions to provide seamless authentication between them. This lab outlines the key setup steps.
Why JWT?
- Stateless: no need for a shared session table between apps.
- Portable: both apps can verify the token with the same signing secret.
- Flexible: tokens carry only the claims you need (
userId
,role
, etc.).
Configuration Steps
1. Shared Secret
Both apps must use the same NEXTAUTH_SECRET
(or equivalent in your auth system).
NEXTAUTH_SECRET=super-secret-shared-value
2. Enable JWT Sessions
// next-auth.config.ts
export const authOptions = {
session: {
strategy: "jwt",
},
};
3. Cookie Domain
Scope the session cookie to the root domain so it’s valid across subdomains:
cookies: {
sessionToken: {
name: "next-auth.session-token",
options: {
domain: ".example.com", // note the leading dot
path: "/",
secure: true, // HTTPS required
sameSite: "lax", // or "none" if you need embedded contexts
},
},
},
4. Environment-Specific URLs
Set each app’s NEXTAUTH_URL
:
# labs app
NEXTAUTH_URL=https://labs.example.com
# courses app
NEXTAUTH_URL=https://courses.example.com
Flow
- User logs in at
labs.example.com
. - Session cookie (
.example.com
) is set. - User visits
courses.example.com
; browser sends the same cookie. courses
verifies JWT with the shared secret → user is authenticated.
Security Notes
- Always use HTTPS (
secure: true
cookies won’t work on plain HTTP). - Rotate the shared secret if compromised.
- Store only necessary claims in the JWT.
- For enterprise needs (revocation, audits), migrate later to DB sessions with a shared session store.
Key Takeaways
- JWT sessions + shared secret + root cookie domain = seamless subdomain SSO.
- Start with JWT for simplicity; move to DB sessions if you need central control.