Overview
Shrtnr uses NextAuth.js v5 for authentication with a credentials-based provider. Authentication is session-based using JWT tokens, with sessions stored in HTTP-only cookies for security.Authentication Flow
User Registration
Users create an account via the
/api/auth/register endpoint with email and password.Sign In
Users authenticate through NextAuth’s built-in credential flow at
/api/auth/signin/credentials.Session Creation
NextAuth creates a JWT token containing user ID and email, stored in an HTTP-only cookie.
Session Configuration
Sessions are configured with the following settings (defined inauth.ts:40):
- Strategy: JWT (no database session storage)
- Max Age: 30 days
- Storage: HTTP-only cookies (secure in production)
Registration Endpoint
POST /api/auth/register
Create a new user account. Request Body:email(required): Valid email address (case-insensitive)password(required): Minimum 8 charactersname(optional): User’s display name
Passwords are hashed using bcrypt with 10 salt rounds before storage (
auth/register/route.ts:22).Authentication Endpoint
POST /api/auth/callback/credentials
NextAuth handles credential-based authentication through its built-in handlers. This endpoint is managed by NextAuth and uses the configuration inauth.ts.
How It Works:
- NextAuth receives credentials (email and password)
- The
authorizefunction queries the database for the user (auth.ts:21-26) - Password is verified using bcrypt (
auth.ts:30) - If valid, a JWT token is created with user information
- Token is stored in an HTTP-only cookie
Using Sessions in API Routes
All protected API routes use theauth() helper to retrieve the current session:
Session Object Structure
The session object contains the following user information:auth.ts:41-56):
Authentication Requirements by Endpoint
POST /api/shorten
Optional - Custom slugs require auth, anonymous gets random code
GET /api/links
Required - Only authenticated users can list their links
PATCH /api/links/[id]
Required - Only link owner can update
DELETE /api/links/[id]
Required - Only link owner can delete
Security Features
Password Security
- Passwords hashed with bcrypt (10 rounds)
- Minimum password length: 8 characters
- Password hashes stored in
users.password_hashcolumn - Plain-text passwords never stored
Session Security
- HTTP-only cookies: Prevents XSS attacks from accessing tokens
- JWT tokens: Stateless authentication, no database lookups per request
- 30-day expiration: Automatic session timeout
- Secure flag in production (HTTPS only)
Email Handling
- Emails normalized: trimmed and lowercased (
auth.ts:18) - Unique constraint on email column prevents duplicates
- Email validation using regex pattern (
auth/register/route.ts:15)
Environment Variables
Required environment variables for authentication:Generate a secure
AUTH_SECRET using: openssl rand -base64 32Custom Sign-In Page
Shrtnr uses a custom sign-in page instead of NextAuth’s default (auth.ts:37-39):
Best Practices
Always Check Sessions
Validate
session?.user?.id exists before accessing protected resourcesReturn Proper Status Codes
Use
401 for missing auth, 403 for insufficient permissionsSecure Environment Variables
Never commit
AUTH_SECRET to version controlUse HTTPS in Production
Ensure cookies are transmitted securely
Example: Protected API Route
Here’s a complete example of a protected endpoint (api/links/route.ts:5-17):
Sign Out
To sign out, use NextAuth’s built-in signOut function:Troubleshooting
Session is null even after signing in
Session is null even after signing in
- Verify
AUTH_SECRETis set in environment variables - Check that cookies are enabled in the browser
- Ensure the request includes credentials (same-origin)
- Verify database connection is working
Email already registered error
Email already registered error
This occurs when the email exists in the database (PostgreSQL unique constraint
23505). The user should sign in instead or use password recovery.Database not set up error
Database not set up error
Run the database initialization script:This creates the required
users, urls, and clicks tables.Next Steps
API Overview
Explore all available API endpoints
Shorten Endpoint
Create short links with authentication