Implementing Authentication with Next.js and Express

React
Security
September 5, 2024

Learn how to implement full Authentication and Authorization using JWT and httpOnly cookies with Next.js server and client components and Express.js Backend.

Why Combine Next.js Server Components with Express Backend?

Next.js server components leverage the strengths of both Next.js and Express.js. With this approach, you get the best of both worlds, such as SSR, SSG, and improved SEO from Next.js, while allowing Express.js to handle backend logic and routing.

Why Use HttpOnly Cookies Instead of Local Storage?

  • Security against XSS: HttpOnly cookies are more resistant to XSS attacks since they are inaccessible via JavaScript, whereas local storage is vulnerable to XSS.
  • Protection against CSRF: HttpOnly cookies, when used with the SameSite flag, provide protection against CSRF attacks.

API Proxies in Next.js

API proxies are crucial for handling authentication when making requests from client components to a backend. By creating an API route in Next.js, you ensure that cookies are correctly attached and sent with the request.

Code Example

import { getToken } from "@/lib/cookie";
import { createOptions } from "@/lib/user";
import { NextRequest, NextResponse } from "next/server";

export async function GET(req: NextRequest) {
  const url = 'https://express-api.com/api/auth';
  const token = await getToken();
  const res = await fetch(url, {
    method: 'GET',
    credentials: 'include',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${token}`,
    },
    next: { revalidate: 0 },
  });
  const data = await res.json();
  return NextResponse.json({ message: data.message });
}

Best Practices

  • Use HTTPS to encrypt communications
  • Implement short token lifetimes for security
  • Use secure cookie settings (e.g., HttpOnly, SameSite)
  • Regularly audit your security setup

Implementation Steps

  1. Set up your Express.js backend with JWT authentication
  2. Configure Next.js API routes to proxy requests to your backend
  3. Implement secure cookie handling in your authentication flow
  4. Set up protected routes and middleware for authorization
  5. Test your implementation thoroughly for security vulnerabilities

Common Pitfalls to Avoid

  • Token Storage: Never store sensitive tokens in localStorage or sessionStorage
  • Cookie Configuration: Always set appropriate flags (HttpOnly, Secure, SameSite)
  • Error Handling: Implement proper error handling for authentication failures
  • Token Refresh: Don't forget to implement token refresh mechanisms