
- Next.js - Home
- Next.js - Overview
- Next.js - Project Setup
- Next.js - Folder Structure
- Next.js - App Router
- Next.js - Page Router
- Next.js Features
- Next.js - Pages
- Next.js - Data Fetching
- Next.js - ISR
- Next.js - Static File Serving
- Next.js - Pre-Rendering
- Next.js - Partial Pre Rendering
- Next.js - Server Side Rendering
- Next.js - Client Side Rendering
- Next.js Routing
- Next.js - Routing
- Next.js - Nested Routing
- Next.js - Dynamic Routing
- Next.js - Parallel Routing
- Next.js - Imperative Routing
- Next.js - Shallow Routing
- Next.js - Intercepting Routes
- Next.js - Redirecting Routes
- Next.js - Navigation and Linking
- Next.js Configuration
- Next.js - TypeScript
- Next.js - Environment Variables
- Next.js - File Conventions
- Next.js - ESLint
- Next.js API & Backend
- Next.js - API Routes
- Next.js - Dynamic API Routes
- Next.js - Route Handlers
- Next.js - API MiddleWares
- Next.js - Response Helpers
- Next.js API Reference
- Next.js - CLI Commands
- Next.js - Functions
- Next.js - Directives
- Next.js - Components
- Next.js - Image Component
- Next.js - Font Component
- Next.js - Head Component
- Next.js - Form Component
- Next.js - Link Component
- Next.js - Script Component
- Next.js Styling & SEO
- Next.js - CSS Support
- Next.js - Global CSS Support
- Next.js - Meta Data
- Next.js Advanced Topics
- Next.js - Error Handling
- Next.js - Server Actions
- Next.js - Fast Refresh
- Next.js - Internationalization
- Next.js - Authentication
- Next.js - Session Management
- Next.js - Authorization
- Next.js - Caching
- Next.js - Data Caching
- Next.js - Router Caching
- Next.js - Full Route Caching
- Next.js - Request Memoization
- Next.js Performance Optimization
- Next.js - Optimizations
- Next.js - Image Optimization
- Next.js - Lazy Loading
- Next.js - Font Optimization
- Next.js - Video Optimization
- Next.js - Script Optimization
- Next.js - Memory Optimization
- Next.js - Using OpenTelemetry
- Next.js - Package Bundling Optimization
- Next.js Testing
- Next.js - Testing
- Next.js - Testing with Jest
- Next.js - Testing with Cypress
- Next.js - Testing with Vitest
- Next.js - Testing with Playwright
- Next.js Debugging & Deployment
- Next.js - Debugging
- Next.js - Deployment
- Next.js Useful Resources
- Next.js - Interview Questions
- Next.js - Quick Guide
- Next.js - Useful Resources
- Next.js - Discussion
Next.js - Authentication
What is Authentication?
Authentication is the process of verifying the identity of a user. It is used to ensure that the user is who they claim to be. In web applications, authentication is done by verifying the user's credentials, such as username and password. The authentication process has following three steps:
- Take user's credentials
- Validate the credentials
- Verify the credentials with database
Authentication in Next.js
In Next.js, authentication of a user is done in three steps. The section below explains each steps of the authentication in Next.js.
Create a Next.js Form
In web applications, forms are used to take credentials from user. You can use Next.js <Form> component to create an applications form in Next.js. The <Form> extends functionality of HTML form tag and provide extra features for client-side navigation on submission, prefetching of loading UI, and progressive enhancement.
In the code below, we are creating a simple form with email and password fields.
// app/ui/signup-form.tsx import { signup } from '@/app/actions/auth' export function SignupForm() { return ( <Form action={signup}> <div> <label htmlFor="email">Email</label> <input id="email" name="email" type="email" placeholder="Email" /> </div> <div> <label htmlFor="password">Password</label> <input id="password" name="password" type="password" /> </div> <button type="submit">Sign Up</button> </Form> ) }
Validate Form Fields on the Server
Form validations are used to ensure that the data entered by the user is in valid format. This step will prevent unwanted data from being submitted to the server and reduce the server load.
Next.js provides server actions to validate the form fields on the server. You can use schema validation library like Zod or Yup to validate the form fields. In the code below, we are using Zod to validate the form fields.
// app/actions/auth.ts import { z } from 'zod' export const SignupFormSchema = z.object({ email: z.string().email({ message: 'Enter a valid email.' }).trim(), password: z .string() .regex(/[a-zA-Z]/, { message: 'Contain at least one letter.' }) .regex(/[0-9]/, { message: 'Contain at least one number.' }) .regex(/[^a-zA-Z0-9]/, { message: 'Contain at least one special character.', }) .trim(), }) export type FormState = | { errors?: { name?: string[] email?: string[] password?: string[] } message?: string } | undefined
Check User Credentials
After validating the user entries, next step is to check the user credentials with the database. Based on this information, you can create a new user account or sign in the user. See the cod e below
export async function signup(state: FormState, formData: FormData) { // 1. Validate form fields // ... // 2. Prepare data for insertion into database const { name, email, password } = validatedFields.data // e.g. Hash the user's password before storing it const hashedPassword = await bcrypt.hash(password, 10) // 3. Insert the user into the database or call an Auth Library's API const data = await db .insert(users) .values({ name, email, password: hashedPassword, }) .returning({ id: users.id }) const user = data[0] if (!user) { return { message: 'An error occurred while creating your account.', } } // TODO: // 4. Create user session // 5. Redirect user }