---
title: "Authentication and Security"
description: "Implementing robust authentication and security practices protects user accounts, private routes, and sensitive application data. This guide covers how to handle login flows using cookies and serve..."
last_updated: "2026-09-23T10:57:21.220999+00:00"
canonical_url: "https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/guide/how-to-guides/authentication-and-security"
---

## Overview

### Overview
Implementing robust authentication and security practices protects user accounts, private routes, and sensitive application data. This guide covers how to handle login flows using cookies and server actions, secure private pages, protect against cross-site request vulnerabilities, and configure security headers.

---

## Managing User Login and Cookies

### Overview
User login flows typically rely on setting and managing secure HTTP cookies. Cookies handle session state between the browser and the server.

> [!IMPORTANT]
> The `cookies()` API returns a Promise and must be unwrapped using `await` or `React.use()` before you can read or check its properties. Accessing cookie properties synchronously will result in a runtime error.

### Working with Cookies in Server Actions and Route Handlers
You can securely set, update, or clear authentication cookies inside Server Actions and Route Handlers. 

```typescript
import { cookies } from 'next/headers'

export async function POST(request: Request) {
  const cookieStore = await cookies()
  
  // Set an authentication cookie upon successful login
  cookieStore.set({
    name: 'session_token',
    value: 'encrypted-user-session-string',
    httpOnly: true,
    path: '/',
    secure: process.env.NODE_ENV !== 'development',
    sameSite: 'lax',
  })

  return new Response('Logged in successfully', { status: 200 })
}
```

> [!WARNING]
> Cookies can only be modified inside a Server Action or Route Handler. Attempting to call mutation methods like `.set()` or `.delete()` directly inside a standard Server Component rendering phase will throw an error.

---

## Protecting Private Routes and Handling Access

### Overview
To secure private routes and restrict unauthorized users from viewing sensitive data, you can check user sessions and trigger authorization interrupts.

### Using the Unauthorized Utility
When a user attempts to access a restricted resource without proper credentials, you can trigger an unauthorized response. 

> [!NOTE]
> The `unauthorized()` utility is currently an experimental feature and requires enabling `authInterrupts` in your configuration.

Supported contexts for invoking authorization helpers:
* Server Components
* Route Handlers
* Server Actions

---

## Securing Sensitive Data and Requests

### Overview
To protect your application from common web vulnerabilities like Cross-Site Request Forgery (CSRF) and cache poisoning, the server implements strict validation checks.

### Cross-Origin Development Protection
During development, cross-origin access to internal resources is blocked by default for safety. If your setup requires loading the development server from a custom host or separate origin, you must add that host to your allowed origins list.

> [!TIP]
> To allow specific hosts to communicate with your development server securely, configure the `allowedDevOrigins` setting in your project configuration file.

```javascript
module.exports = {
  allowedDevOrigins: ['my-custom-domain.local'],
}
```

### Server Actions and Encryption
Server Actions utilize encryption keys to secure data payloads. By default, an encryption key is automatically generated and managed in your local cache directory. If you need to supply a custom encryption key across deployments, use the designated environment variable:

* Environment variables: `NEXT_SERVER_ACTIONS_ENCRYPTION_KEY`

---

## Configuring Security Headers

### Overview
Configuring security headers ensures that your application defends against browser-level attacks, clickjacking, and MIME-type sniffing. You can define custom headers in your project configuration.

```mermaid
flowchart TD
    A[User Request] --> B[Next.js Route Matching]
    B --> C[Custom Headers Applied]
    C --> D[Secure Response Sent to Browser]
```

> [!CAUTION]
> Setting custom `Cache-Control` headers on internal Next.js assets (`/_next/`) can break default development behavior and production caching mechanisms. Avoid overriding cache rules on internal system routes.

## Related

- [Routing and Navigation](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/guide/core-concepts/routing-and-navigation)
- [Environment and Configuration](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/guide/configuration/environment-and-configuration)


## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/llms.txt) for all pages in this wiki.
