Next.js Auth System

Implement secure user authentication

🔐 What is Next.js Authentication?

Next.js authentication manages user login, registration, and session handling. It uses server actions and middleware to protect routes, verify credentials, and maintain secure user sessions across your application with modern security practices.


// app/login/page.tsx
export default function LoginPage() {
  return (
    <main>
      <h1>Login</h1>
      <form>{/* Login form */}</form>
    </main>
  )
}
                                    

Key Auth Features

🔑

Login

User sign in functionality

// app/login/page.tsx
export default function Login() {
  return <form>Login</form>
}
📝

Register

New user signup

// app/register/page.tsx
export default function Register() {
  return <form>Sign Up</form>
}
🛡️

Protected Routes

Secure private pages

// middleware.ts
export function middleware(req) {
  // Check auth
}
👤

User Profile

Manage user data

// app/profile/page.tsx
export default function Profile() {
  return <div>Profile</div>
}

🔹 Login Form Component

Create a login form with email and password fields using server actions. This form handles user authentication securely on the server side, validating credentials and creating sessions for authenticated users.

// app/login/page.tsx
export default function LoginPage() {
  async function handleLogin(formData) {
    'use server'
    const email = formData.get('email')
    const password = formData.get('password')
    
    // Authenticate user
    console.log('Logging in:', email)
  }

  return (
    <div>
      <h1>Login</h1>
      <form action={handleLogin}>
        <input 
          type="email" 
          name="email" 
          placeholder="Email" 
          required 
        />
        <input 
          type="password" 
          name="password" 
          placeholder="Password" 
          required 
        />
        <button type="submit">Login</button>
      </form>
      <p>Don't have an account? <a href="/register">Sign up</a></p>
    </div>
  )
}

Output:

Login

Don't have an account? Sign up

🔹 Registration Form

Build a signup form to create new user accounts with validation. This component collects user information, validates input, and creates new accounts with secure password hashing on the server.

// app/register/page.tsx
export default function RegisterPage() {
  async function handleRegister(formData) {
    'use server'
    const name = formData.get('name')
    const email = formData.get('email')
    const password = formData.get('password')
    
    // Create new user
    console.log('Creating user:', email)
  }

  return (
    <div>
      <h1>Create Account</h1>
      <form action={handleRegister}>
        <input 
          type="text" 
          name="name" 
          placeholder="Full Name" 
          required 
        />
        <input 
          type="email" 
          name="email" 
          placeholder="Email" 
          required 
        />
        <input 
          type="password" 
          name="password" 
          placeholder="Password" 
          required 
        />
        <button type="submit">Sign Up</button>
      </form>
      <p>Already have an account? <a href="/login">Login</a></p>
    </div>
  )
}

Output:

Create Account

Already have an account? Login

🔹 Protected Route Middleware

Use middleware to protect routes and redirect unauthorized users. This code runs before page rendering to check authentication status and control access to protected areas of your application.

// middleware.ts
import { NextResponse } from 'next/server'

export function middleware(request) {
  // Check if user is authenticated
  const isAuthenticated = request.cookies.get('auth-token')
  
  // Protect dashboard routes
  if (request.nextUrl.pathname.startsWith('/dashboard')) {
    if (!isAuthenticated) {
      return NextResponse.redirect(new URL('/login', request.url))
    }
  }
  
  return NextResponse.next()
}

export const config = {
  matcher: ['/dashboard/:path*', '/profile/:path*']
}

🔹 User Profile Page

Display and edit user information on a protected profile page. This page shows authenticated user data and allows updates to account settings with proper authorization checks.

// app/profile/page.tsx
async function getUser() {
  // Fetch current user data
  return {
    name: 'John Doe',
    email: '[email protected]',
    joined: '2024-01-15'
  }
}

export default async function ProfilePage() {
  const user = await getUser()
  
  return (
    <div>
      <h1>My Profile</h1>
      <div>
        <p><strong>Name:</strong> {user.name}</p>
        <p><strong>Email:</strong> {user.email}</p>
        <p><strong>Member since:</strong> {user.joined}</p>
      </div>
      <button>Edit Profile</button>
      <button>Logout</button>
    </div>
  )
}

Output:

My Profile

Name: John Doe

Email: [email protected]

Member since: 2024-01-15

🔹 Session Management

Handle user sessions with cookies and tokens for persistent authentication. This utility manages login state across page refreshes and provides functions to check authentication status throughout your app.

// lib/auth.ts
import { cookies } from 'next/headers'

export async function createSession(userId) {
  // Create auth token
  const token = 'user-token-' + userId
  cookies().set('auth-token', token, {
    httpOnly: true,
    secure: true,
    maxAge: 60 * 60 * 24 * 7 // 7 days
  })
}

export async function getSession() {
  const token = cookies().get('auth-token')
  return token?.value
}

export async function deleteSession() {
  cookies().delete('auth-token')
}

🧠 Test Your Knowledge

What file is used to protect routes in Next.js?