Authentication
This guide explains how to configure authentication for the Zero Kelvin web application. The application uses Auth.js (NextAuth.js v5) for authentication, supporting multiple OAuth providers including social login and OIDC.
Overview
The authentication system provides:
- Social authentication (Google, Facebook, Apple, LinkedIn)
- OpenID Connect (OIDC) support (including self-hosted providers like Authelia)
- Session management with JWT
- Gravatar-based user avatars
- Secure sign-in and sign-out flows
Quick Start
- Copy the example environment file:
cp apps/web/.env.example apps/web/.env.local
- Generate an
AUTH_SECRET:
openssl rand -base64 32
-
Add your OAuth provider credentials (see provider-specific guides below)
-
Start the development server:
nx dev web
Environment Variables
| Variable | Description | Required |
|---|---|---|
AUTH_SECRET | Secret key for encrypting tokens and cookies | Yes |
AUTH_GOOGLE_ID | Google OAuth Client ID | For Google auth |
AUTH_GOOGLE_SECRET | Google OAuth Client Secret | For Google auth |
AUTH_FACEBOOK_ID | Facebook App ID | For Facebook auth |
AUTH_FACEBOOK_SECRET | Facebook App Secret | For Facebook auth |
AUTH_APPLE_ID | Apple Service ID | For Apple auth |
AUTH_APPLE_SECRET | Apple Private Key | For Apple auth |
AUTH_LINKEDIN_ID | LinkedIn Client ID | For LinkedIn auth |
AUTH_LINKEDIN_SECRET | LinkedIn Client Secret | For LinkedIn auth |
AUTH_AUTHELIA_ISSUER | Authelia instance URL | For Authelia OIDC |
AUTH_AUTHELIA_ID | Authelia Client ID | For Authelia OIDC |
AUTH_AUTHELIA_SECRET | Authelia Client Secret | For Authelia OIDC |
Architecture
The authentication system consists of:
/apps/web/src/auth.ts- Auth.js configuration/apps/web/src/app/api/auth/[...nextauth]/route.ts- API route handler/apps/web/src/components/auth-provider.tsx- React context provider/apps/web/src/components/user-menu.tsx- User menu component/apps/web/src/app/auth/signin/page.tsx- Custom sign-in page
Adding a New Provider
To add a new authentication provider:
- Import the provider in
auth.ts:
import NewProvider from "next-auth/providers/newprovider";
- Add the provider to the
providersarray:
export const { handlers, auth, signIn, signOut } = NextAuth({
providers: [
// ... existing providers
NewProvider({
clientId: process.env.AUTH_NEWPROVIDER_ID,
clientSecret: process.env.AUTH_NEWPROVIDER_SECRET,
}),
],
});
-
Add the environment variables to
.env.local -
Update the sign-in page to include the new provider button
Custom OIDC Provider
To add a custom OpenID Connect provider:
import NextAuth from "next-auth";
export const { handlers, auth, signIn, signOut } = NextAuth({
providers: [
{
id: "my-oidc-provider",
name: "My OIDC Provider",
type: "oidc",
issuer: "https://my-oidc-provider.com",
clientId: process.env.AUTH_OIDC_ID,
clientSecret: process.env.AUTH_OIDC_SECRET,
},
],
});
Session Management
Server Components
Access the session in server components:
import { auth } from "@/auth"
export default async function Page() {
const session = await auth()
if (!session) {
return <div>Not authenticated</div>
}
return <div>Hello, {session.user?.name}</div>
}
Client Components
Access the session in client components using the useSession hook:
"use client"
import { useSession } from "next-auth/react"
export function MyComponent() {
const { data: session, status } = useSession()
if (status === "loading") {
return <div>Loading...</div>
}
if (!session) {
return <div>Not authenticated</div>
}
return <div>Hello, {session.user?.name}</div>
}
Protecting Pages
Protect pages by checking the session:
import { auth } from "@/auth"
import { redirect } from "next/navigation"
export default async function ProtectedPage() {
const session = await auth()
if (!session) {
redirect("/auth/signin")
}
return <div>Protected content</div>
}
User Avatars
The application automatically generates Gravatar URLs based on the user's email address. If the OAuth provider returns a profile image, that will be used instead.
import { getGravatarUrl } from "@/lib/gravatar";
// Generate a Gravatar URL
const avatarUrl = getGravatarUrl(user.email, 80);
Troubleshooting
Common Issues
- "Invalid OAuth credentials" - Verify your client ID and secret are correct
- "Redirect URI mismatch" - Check that your OAuth app's redirect URI matches
http://localhost:3000/api/auth/callback/{provider}for development - "Session not persisting" - Ensure
AUTH_SECRETis set and consistent across deployments
Debug Mode
Enable debug logging by adding to your .env.local:
AUTH_DEBUG=true