Aller au contenu principal

Publié le · Mis à jour le 2 octobre 2026

Implémenter une Basic Auth dans Next.js App Router

Dimitri Dumont
Dimitri Dumont

Développeur React & Next.js freelance

Que ce soit pour implémenter une simple authentification ou pour protéger l'accès à votre application le temps de sa mise en production, l'authentification "Basic Auth" ou aussi appelée "HTTP authentication" est une solution simple et efficace. Dans ce tutoriel, nous allons voir comment implémenter une Basic Auth dans un projet Next.js avec l'app router.

Le code est écrit pour Next.js 16, où le fichier middleware.ts a été renommé proxy.ts. Sur Next.js 14 ou 15, gardez le nom middleware.ts et nommez la fonction middleware : le reste du code est identique.

Qu'est-ce que Basic Auth ?

Pour comprendre comment l'implémenter dans un projet Next.js, il est utile de comprendre le fonctionnement de cette authentification HTTP.

Son fonctionnement est relativement simple :

  1. Un visiteur tente d'accéder à une page protégée.
  2. Le serveur envoie une réponse avec un statut 401 et fournit l'information pour permettre à l'utilisateur de s'authentifier grâce à un en-tête de réponse WWW-Authenticate.
  3. Le visiteur s'authentifie grâce à une fenêtre qui contient le formulaire d'authentification.
  4. Le navigateur encode en base64 les identifiants du visiteur et les transmet au serveur en incluant un en-tête Authorization.
  5. Le serveur vérifie les identifiants. S'ils sont valides, il renvoie la page demandée. Sinon, il renvoie de nouveau une réponse 401.
  6. Le navigateur garde ces identifiants en mémoire et les renvoie à chaque requête, en général jusqu'à sa fermeture.

Les étapes pour implémenter Basic Auth dans Next.js

Pour implémenter une "Basic Auth" dans un projet Next.js avec l'app router, il faut suivre ces étapes :

  1. Déclarer des variables d'environnement pour stocker des identifiants.
  2. Créer une route handler pour proposer une interface d'authentification à l'utilisateur.
  3. Créer un fichier proxy.ts pour vérifier si l'utilisateur est authentifié.

1. Déclaration des variables d'environnement

Pour cet article, nous allons définir les identifiants dans les variables d'environnement. Vous pouvez également ajouter une autre variable d'environnement qui servira à activer ou non l'authentification en fonction de certains cas comme des tests end-to-end ou des tests Lighthouse.

.env.local
BASIC_AUTH_DISABLED=false
BASIC_AUTH_USER=username
BASIC_AUTH_PASSWORD=password

2. Création de la route handler

Cette route handler va permettre à Next.js de renvoyer une erreur 401 pour demander à l'utilisateur de s'authentifier via une interface directement intégrée dans le navigateur.

src/app/api/auth/route.ts
export const GET = () => {
  return new Response("Authentication Required!", {
    status: 401,
    headers: {
      "WWW-Authenticate": 'Basic realm="private_pages"',
    },
  })
}

3. Configuration du proxy

Une fois les variables d'environnement initialisées et la route handler créée, nous pouvons créer le fichier proxy.ts pour protéger l'accès à notre application Next.js. Il se place au même niveau que le dossier app.

src/proxy.ts
import { NextResponse } from "next/server"
import type { NextRequest } from "next/server"
 
export function proxy(req: NextRequest) {
  if (
    process.env.BASIC_AUTH_DISABLED === "true" ||
    process.env.NODE_ENV === "development"
  )
    return NextResponse.next()
 
  const basicAuth = req.headers.get("authorization")
 
  if (basicAuth) {
    const authValue = basicAuth.split(" ")[1]
 
    const credentials = atob(authValue)
    const separatorIndex = credentials.indexOf(":")
    const username = credentials.slice(0, separatorIndex)
    const password = credentials.slice(separatorIndex + 1)
 
    if (
      username === process.env.BASIC_AUTH_USER &&
      password === process.env.BASIC_AUTH_PASSWORD
    )
      return NextResponse.next()
  }
 
  const url = req.nextUrl
  url.pathname = "/api/auth"
 
  return NextResponse.rewrite(url)
}
 
export const config = {
  matcher: ["/"],
}

Pour commencer, nous vérifions si l'authentification est désactivée grâce à une variable d'environnement ou si nous sommes dans un environnement de développement. Si cette condition est vraie, alors nous n'utilisons pas l'authentification.

src/proxy.ts
if (
  process.env.BASIC_AUTH_DISABLED === "true" ||
  process.env.NODE_ENV === "development"
)
  return NextResponse.next()

Si l'authentification doit être utilisée, alors nous commençons par récupérer la valeur du header authorization depuis la requête entrante. Si ce header contient une valeur, alors nous tentons de récupérer les identifiants username et password.

Le nom d'utilisateur et le mot de passe sont séparés par le premier :. Un mot de passe peut lui-même contenir ce caractère, d'où le découpage sur le premier séparateur uniquement.

Si ces valeurs correspondent aux identifiants présents dans les variables d'environnement, alors l'utilisateur est authentifié et il peut accéder à l'URL qu'il souhaite.

src/proxy.ts
const basicAuth = req.headers.get("authorization")
 
if (basicAuth) {
  const authValue = basicAuth.split(" ")[1]
 
  const credentials = atob(authValue)
  const separatorIndex = credentials.indexOf(":")
  const username = credentials.slice(0, separatorIndex)
  const password = credentials.slice(separatorIndex + 1)
 
  if (
    username === process.env.BASIC_AUTH_USER &&
    password === process.env.BASIC_AUTH_PASSWORD
  )
    return NextResponse.next()
}

Sinon, la requête est réécrite vers la route handler, qui lui demande de s'authentifier.

src/proxy.ts
const url = req.nextUrl
url.pathname = "/api/auth"
 
return NextResponse.rewrite(url)

Enfin, grâce à l'objet config vous pouvez choisir quelles URLs demandent une authentification. Avec matcher: ["/"], seule la page d'accueil est protégée.

src/proxy.ts
export const config = {
  matcher: ["/"],
}

Pour protéger tout le site, utilisez un pattern qui exclut les routes API et les fichiers statiques. Sans cette exclusion, le CSS, le JavaScript et les images seraient bloqués eux aussi :

src/proxy.ts
export const config = {
  matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
}

FAQ

Basic Auth est-elle sécurisée pour une application en production ?

Basic Auth ne doit pas être utilisée seule pour protéger des données sensibles en production. Les identifiants sont encodés en base64, pas chiffrés. Elle convient pour protéger temporairement un environnement de staging ou de préproduction. Sans HTTPS, ils circulent en clair. Pour authentifier de vrais utilisateurs en production, il faut une solution dédiée comme Auth.js (ex-NextAuth.js), Auth0 ou Clerk.

Comment protéger plusieurs routes avec Basic Auth ?

Le matcher accepte un tableau de patterns. Par exemple, matcher: ["/", "/admin/:path*", "/api/protected/:path*"] protège la page d'accueil, toutes les routes admin et certaines routes API. Les patterns utilisent la syntaxe de matching de Next.js.

Comment se déconnecter d'une Basic Auth ?

Il n'existe pas de méthode standard pour se déconnecter. Le navigateur garde les identifiants en mémoire et les renvoie à chaque requête. La solution fiable est de fermer le navigateur. C'est une limite de l'authentification HTTP Basic.

Peut-on utiliser Basic Auth avec des tests end-to-end ?

Oui, en désactivant l'authentification via la variable d'environnement. La variable BASIC_AUTH_DISABLED=true permet de désactiver l'authentification pendant les tests Cypress ou Playwright. Cela évite de devoir gérer la fenêtre d'authentification du navigateur dans les scripts de test.

Conclusion

Implémenter une "Basic Authentification" ou "HTTP authentication" dans une application Next.js qui utilise l'app router n'est pas très compliqué et peut vous permettre de sécuriser l'accès à votre application pour certains cas.

Cette authentification peut être utilisée pour empêcher l'accès à votre site internet ou à votre application Next.js le temps de développer votre projet ou pour des fonctionnalités en cours de développement.

Dimitri Dumont

Dimitri Dumont

Développeur React & Next.js freelance depuis 8 ans, 33 entreprises accompagnées depuis 2018. J'écris ici ce que je constate en mission : un produit ralentit presque toujours pour les mêmes raisons, une architecture posée dans l'urgence, pas de tests, une mise en production qui fait peur. Mon travail consiste à construire des produits qui n'en arrivent pas là, et à remettre sur pied ceux qui y sont déjà. Mon parcours

La suite

Ce que ça donne sur votre code

Lire un article et lire une vraie codebase sont deux exercices différents. Je lis la vôtre et je vous dis ce qui ralentit, ce que ça coûte de le corriger, et dans quel ordre.

Articles similaires