vendredi 25 septembre 2026

À propos

Contact

Headless & API

Remix et l’authentification headless : sessions serveur plutôt que JWT client

Pour un espace membre WordPress headless, Remix permet de gérer une session serveur avec cookies plutôt que de stocker un token JWT côté client. Définition, fonctionnement et cas d'usage.

Par Clément Hadrot • 6 septembre 2023 • 4 min de lecture • Aucun commentaire
Remix et l'authentification headless : sessions serveur plutôt que JWT client

Cet article ne traite pas de Remix en général, un sujet déjà couvert dans un autre article de ce blog consacré à ses fondamentaux. Il porte sur un choix précis, souvent tranché trop vite : pour un espace membre WordPress headless, faut-il stocker un jeton JWT côté client comme on le ferait avec la plupart des frameworks front, ou s’appuyer sur les sessions serveur que Remix rend particulièrement naturelles grâce à son exécution côté serveur systématique ?

Ce qu’est une session serveur, par opposition à un JWT client

Un JWT stocké côté client, dans le localStorage ou un cookie non protégé, transporte lui-même toute l’information nécessaire à l’authentification : un serveur qui le reçoit peut le vérifier sans consulter de base de données, simplement en validant sa signature. C’est rapide et sans état à maintenir côté serveur, mais cela expose le jeton à toute faille XSS capable d’exécuter du JavaScript arbitraire dans le navigateur du visiteur.

Une session serveur inverse cette logique : le navigateur ne reçoit qu’un identifiant de session opaque, stocké dans un cookie marqué HttpOnly, donc totalement inaccessible à n’importe quel script JavaScript, même en cas d’injection réussie. Le serveur, lui, conserve la correspondance entre cet identifiant et les informations réelles de session, généralement en mémoire ou dans un magasin dédié comme Redis.

Comment Remix rend cette approche naturelle

Remix exécute systématiquement son code de chargement de données côté serveur, ce qui en fait un candidat idéal pour manipuler une session sans jamais exposer d’information sensible au client. Le module createCookieSessionStorage fourni nativement encapsule cette logique :

// app/session.server.js
import { createCookieSessionStorage } from '@remix-run/node'

export const { getSession, commitSession, destroySession } =
  createCookieSessionStorage({
    cookie: {
      name: '__session',
      httpOnly: true,
      secure: process.env.NODE_ENV === 'production',
      sameSite: 'lax',
      secrets: [process.env.SESSION_SECRET],
      maxAge: 60 * 60 * 24 * 7,
    },
  })

Le fonctionnement interne, étape par étape

À la connexion, une action Remix authentifie le visiteur auprès de WordPress via un point de terminaison dédié, puis stocke uniquement l’identifiant de l’utilisateur dans la session, jamais le mot de passe ni même un jeton d’accès WordPress complet :

export async function action({ request }) {
  const formData = await request.formData()

  const reponse = await fetch('https://api.exemple.fr/wp-json/jwt-auth/v1/token', {
    method: 'POST',
    body: JSON.stringify({
      username: formData.get('email'),
      password: formData.get('motDePasse'),
    }),
    headers: { 'Content-Type': 'application/json' },
  })

  if (!reponse.ok) {
    return { erreur: 'Identifiants invalides' }
  }

  const { token, user_id } = await reponse.json()
  const session = await getSession()
  session.set('userId', user_id)
  session.set('wpToken', token)

  return redirect('/mon-compte', {
    headers: { 'Set-Cookie': await commitSession(session) },
  })
}
L'essentiel à retenir : Le cookie de session ne quitte jamais le serveur Remix ; Aucun jeton n'est jamais lisible par du JavaScript côté client ; Le renouvellement de session devient invisible pour le visiteur

Le jeton JWT WordPress lui-même existe toujours quelque part, puisque l’API REST en a besoin pour authentifier les requêtes suivantes, mais il ne quitte jamais le serveur Remix : il reste enfermé dans la session côté serveur, jamais transmis tel quel au navigateur.

Cas d’usage : où cette approche fait la différence

  • Un espace membre affichant des informations sensibles (historique de commandes, données personnelles) bénéficie directement de cette protection contre le vol de jeton par script malveillant.
  • Un site avec plusieurs onglets ouverts simultanément profite d’une session partagée automatiquement via le cookie, sans synchronisation manuelle entre onglets comme il faudrait le faire avec un jeton en localStorage.
  • Une déconnexion forcée côté serveur (compte suspendu, mot de passe changé) prend effet immédiatement, sans attendre l’expiration naturelle d’un jeton déjà distribué au client.

Les pièges à connaître

  • Une session serveur introduit un état à gérer côté infrastructure : perdre le magasin de sessions (Redis, ou la mémoire du processus) déconnecte tous les visiteurs d’un coup, un risque à anticiper en production.
  • Le SESSION_SECRET utilisé pour signer le cookie doit rester strictement confidentiel et suffisamment complexe, sa fuite permettrait de forger de fausses sessions.
  • Une application distribuée sur plusieurs serveurs nécessite un magasin de sessions partagé entre toutes les instances, jamais une session stockée uniquement en mémoire locale d’un seul serveur.

Le choix entre JWT client et session serveur n’est jamais une question de mode ou de préférence technique : c’est une question de surface d’attaque acceptée, à trancher en fonction de la sensibilité réelle des données manipulées.

En résumé

Remix rend l’approche par session serveur particulièrement simple à mettre en œuvre, grâce à son exécution systématique côté serveur et son module de session intégré. Pour un espace membre WordPress headless manipulant des données sensibles, cette approche réduit nettement la surface d’attaque comparée à un jeton stocké côté client, au prix d’un état serveur à surveiller et à dimensionner correctement.

Partager :

À propos de l'auteur

Clément Hadrot

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi