Back to DocumentationAuthentication
Security & Authentication

Authentication System

Complete guide to NextAuth v5, OAuth providers, and role-based access control in NextReady.

Multi-provider OAuth
Role-based access
Production ready

Authentication Features

Multi-Provider OAuth
Support for Google, GitHub, and credentials-based authentication
  • Google OAuth integration
  • GitHub OAuth integration
  • Email/password authentication
  • Extensible provider system
Role-Based Access Control
Granular permission system with role hierarchy
  • USER, ADMIN, SUPER_ADMIN roles
  • Permission-based authorization
  • Protected routes and components
  • API endpoint security
Session Management
Secure JWT sessions with NextAuth v5
  • Secure JWT token handling
  • Automatic session refresh
  • Server-side session validation
  • Cross-tab synchronization
Developer Experience
Easy setup with comprehensive utilities
  • Type-safe session hooks
  • Middleware protection
  • Development tools
  • Testing utilities

Configuration & Setup

NextAuth v5 Configuration
Main configuration file with providers and callbacks
// auth.config.ts
import type { NextAuthConfig } from "next-auth";
import Google from "next-auth/providers/google";
import GitHub from "next-auth/providers/github";
import Credentials from "next-auth/providers/credentials";
import { signInSchema } from "@/lib/validations";

export const authConfig = {
  providers: [
    Google({
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    }),
    GitHub({
      clientId: process.env.GITHUB_CLIENT_ID!,
      clientSecret: process.env.GITHUB_CLIENT_SECRET!,
    }),
    Credentials({
      async authorize(credentials) {
        const validatedFields = signInSchema.safeParse(credentials);
        
        if (validatedFields.success) {
          const { email, password } = validatedFields.data;
          const user = await getUserByEmail(email);
          
          if (!user || !user.password) return null;
          
          const passwordsMatch = await bcrypt.compare(password, user.password);
          if (passwordsMatch) return user;
        }
        return null;
      },
    }),
  ],
  pages: {
    signIn: "/signin",
    signUp: "/signup",
  },
  callbacks: {
    authorized({ auth, request: { nextUrl } }) {
      const isLoggedIn = !!auth?.user;
      const isOnDashboard = nextUrl.pathname.startsWith('/dashboard');
      
      if (isOnDashboard) {
        if (isLoggedIn) return true;
        return false; // Redirect to login page
      } else if (isLoggedIn) {
        return Response.redirect(new URL('/dashboard', nextUrl));
      }
      return true;
    },
  },
} satisfies NextAuthConfig;

Role-Based Access Control

Permission System
Granular permission system with role hierarchy
// lib/permissions.ts
export enum UserRole {
  USER = "USER",
  ADMIN = "ADMIN", 
  SUPER_ADMIN = "SUPER_ADMIN"
}

export enum Permission {
  USER_READ = "USER_READ",
  USER_WRITE = "USER_WRITE", 
  USER_DELETE = "USER_DELETE",
  FILE_UPLOAD = "FILE_UPLOAD",
  EMAIL_SEND = "EMAIL_SEND",
  ADMIN_PANEL = "ADMIN_PANEL"
}

const rolePermissions: Record<UserRole, Permission[]> = {
  [UserRole.USER]: [
    Permission.USER_READ,
    Permission.FILE_UPLOAD
  ],
  [UserRole.ADMIN]: [
    Permission.USER_READ,
    Permission.USER_WRITE,
    Permission.FILE_UPLOAD, 
    Permission.EMAIL_SEND,
    Permission.ADMIN_PANEL
  ],
  [UserRole.SUPER_ADMIN]: Object.values(Permission)
};

export class PermissionChecker {
  static hasRole(user: User, requiredRole: UserRole): boolean {
    const roleHierarchy = {
      [UserRole.SUPER_ADMIN]: 3,
      [UserRole.ADMIN]: 2,
      [UserRole.USER]: 1
    };
    
    return roleHierarchy[user.role] >= roleHierarchy[requiredRole];
  }

  static hasPermission(user: User, permission: Permission): boolean {
    const userPermissions = rolePermissions[user.role] || [];
    return userPermissions.includes(permission);
  }
}
Protected Components
Protect UI components based on user roles and permissions
// components/auth/ProtectedRoute.tsx
import { useSession } from "next-auth/react";
import { UserRole, Permission } from "@/lib/permissions";
import { PermissionChecker } from "@/lib/permissions";

interface ProtectedRouteProps {
  requiredRole?: UserRole;
  requiredPermission?: Permission;
  children: React.ReactNode;
  fallback?: React.ReactNode;
}

export function ProtectedRoute({
  requiredRole,
  requiredPermission,
  children,
  fallback = <AccessDenied />
}: ProtectedRouteProps) {
  const { data: session, status } = useSession();

  if (status === "loading") {
    return <LoadingSpinner />;
  }

  if (!session) {
    return <SignInPrompt />;
  }

  if (requiredRole && !PermissionChecker.hasRole(session.user, requiredRole)) {
    return fallback;
  }

  if (requiredPermission && !PermissionChecker.hasPermission(session.user, requiredPermission)) {
    return fallback;
  }

  return <>{children}</>;
}

// Usage example
<ProtectedRoute requiredRole={UserRole.ADMIN}>
  <AdminDashboard />
</ProtectedRoute>
API Route Protection
Secure your API endpoints with middleware
// API route with protection
import { withApiMiddleware } from "@/lib/api-middleware";
import { UserRole, Permission } from "@/lib/permissions";

async function handler(request: NextRequest) {
  // Your API logic here
  const users = await db.user.findMany();
  return Response.json(users);
}

export const GET = withApiMiddleware(handler, {
  rateLimit: "default",
  requiredRole: UserRole.ADMIN,
  requiredPermission: Permission.USER_READ,
});

OAuth Provider Setup

Google OAuth
Set up Google authentication

1. Create Google Cloud Project

Go to Google Cloud Console and create a new project

2. Enable Google+ API

Enable the Google+ API in your project

3. Create OAuth Credentials

Create OAuth 2.0 client credentials for web application

4. Configure Redirect URLs

Add your callback URLs (e.g., http://localhost:3000/api/auth/callback/google)

GitHub OAuth
Set up GitHub authentication

1. Register OAuth App

Go to Settings → Developer settings → OAuth Apps

2. Configure Application

Set homepage URL and authorization callback URL

3. Get Credentials

Copy Client ID and generate Client Secret

4. Add to Environment

Add GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET to .env.local

Security Best Practices

Testing Authentication

Test Your Setup
Verify your authentication is working correctly
1

Test OAuth Providers

Try signing in with Google and GitHub to ensure OAuth is configured correctly

2

Verify Role Protection

Test that admin-only pages are properly protected from regular users

3

Check Session Persistence

Ensure sessions persist across browser refreshes and tabs

🔐 Authentication Ready!

Your authentication system is now configured. Ready to learn about other NextReady systems?