Skip to main content

Authentication Plugin

The auth-jwt plugin provides secure JWT-based authentication for your application.

Features

  • JWT access and refresh tokens
  • Password hashing with bcrypt
  • Role-based access control
  • Session management
  • Secure HTTP-only cookies

Installation

npx autodeploybase add auth-jwt

Configuration

autodeploy.config.json
{
"plugins": {
"auth-jwt": {
"enabled": true,
"settings": {
"tokenExpiry": "7d",
"refreshExpiry": "30d",
"algorithm": "HS256"
}
}
}
}

Environment Variables

JWT_SECRET="your-super-secret-key-at-least-32-characters"
JWT_REFRESH_SECRET="another-secret-for-refresh-tokens"

Generated Files

src/
├── app/
│ ├── (auth)/
│ │ ├── login/page.tsx
│ │ └── register/page.tsx
│ └── api/
│ └── auth/
│ ├── login/route.ts
│ ├── register/route.ts
│ ├── logout/route.ts
│ ├── refresh/route.ts
│ └── me/route.ts
├── lib/
│ └── auth.ts
└── plugins/
└── auth-jwt/
├── index.ts
├── provider.tsx
└── hooks/
└── useAuth.ts

Usage

Client-Side

import { useAuth } from '@/plugins/auth-jwt/hooks/useAuth';

export function ProfilePage() {
const { user, isLoading, logout } = useAuth();

if (isLoading) return <div>Loading...</div>;
if (!user) return <div>Not authenticated</div>;

return (
<div>
<h1>Welcome, {user.name}</h1>
<p>Email: {user.email}</p>
<button onClick={logout}>Logout</button>
</div>
);
}

Server-Side

import { getUser, requireAuth, requireAdmin } from '@/lib/auth';

// Get current user (may be null)
export async function GET(request: Request) {
const user = await getUser(request);
// user is User | null
}

// Require authentication
export async function POST(request: Request) {
const user = await requireAuth(request);
// Throws if not authenticated
}

// Require admin role
export async function DELETE(request: Request) {
const user = await requireAdmin(request);
// Throws if not admin
}

Protected Routes

import { AuthGuard } from '@/plugins/auth-jwt/components/AuthGuard';

export default function ProtectedPage() {
return (
<AuthGuard>
<div>This content is protected</div>
</AuthGuard>
);
}

// With role requirement
export default function AdminPage() {
return (
<AuthGuard roles={['ADMIN', 'SUPER_ADMIN']}>
<div>Admin only content</div>
</AuthGuard>
);
}

API Endpoints

POST /api/auth/register

// Request
{
"email": "user@example.com",
"password": "securePassword123",
"name": "John Doe"
}

// Response
{
"user": {
"id": "cuid...",
"email": "user@example.com",
"name": "John Doe",
"role": "USER"
},
"accessToken": "eyJ...",
"refreshToken": "eyJ..."
}

POST /api/auth/login

// Request
{
"email": "user@example.com",
"password": "securePassword123"
}

// Response
{
"user": { ... },
"accessToken": "eyJ...",
"refreshToken": "eyJ..."
}

POST /api/auth/refresh

// Request (token from cookie or body)
{
"refreshToken": "eyJ..."
}

// Response
{
"accessToken": "eyJ...",
"refreshToken": "eyJ..."
}

GET /api/auth/me

// Headers: Authorization: Bearer <accessToken>

// Response
{
"id": "cuid...",
"email": "user@example.com",
"name": "John Doe",
"role": "USER"
}

POST /api/auth/logout

Clears the auth cookies and invalidates the refresh token.

Database Schema

model User {
id String @id @default(cuid())
email String @unique
password String
name String?
role Role @default(USER)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
sessions Session[]
}

model Session {
id String @id @default(cuid())
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
refreshToken String @unique
expiresAt DateTime
createdAt DateTime @default(now())
}

enum Role {
USER
ADMIN
SUPER_ADMIN
}

Security Features

Password Requirements

  • Minimum 8 characters
  • At least one uppercase letter
  • At least one lowercase letter
  • At least one number

Token Security

  • Access tokens: Short-lived (7 days default)
  • Refresh tokens: Longer-lived (30 days default)
  • Refresh token rotation
  • HTTP-only cookies
  • CSRF protection

Rate Limiting

// Built-in rate limiting for auth endpoints
// Default: 5 attempts per minute per IP

Customization

Custom Password Validation

lib/auth.ts
export function validatePassword(password: string): { valid: boolean; error?: string } {
if (password.length < 12) {
return { valid: false, error: 'Password must be at least 12 characters' };
}
// Add more rules...
return { valid: true };
}

Custom User Fields

Extend the Prisma schema:

model User {
// ... existing fields
avatar String?
phone String?
metadata Json?
}

OAuth Integration

For social login, consider adding auth-nextauth:

npx autodeploybase add auth-nextauth