Prérequis

Ce tutoriel fait suite à mon article précédent sur la gestion de l’authentification de l’API Rails avec un frontend React.

Comment ça marche

  • Après la connexion, le navigateur stocke un cookie sécurisé qui est automatiquement ajouté à chaque requête client.
  • Un site attaquant peut forger des requêtes au nom de l’utilisateur, et elles seront authentifiées.

Pourquoi CORS n’arrête pas le CSRF

  • CORS (Cross-Origin Resource Sharing) contrôle qui peut lire les réponses des requêtes cross-origin.
  • Il n’empêche pas le navigateur d’envoyer la requête.
  • CSRF ne repose pas sur la lecture de la réponse — il a juste besoin que le navigateur envoie une requête valide avec des cookies.

Solution : Ajouter un autre vecteur de validation

  • Générer un jeton CSRF sur le serveur.
  • Le renvoyer lors de l’authentification.
  • Inclure le jeton CSRF dans le corps de la requête ou un en-tête personnalisé pour chaque requête changeant l’état.

Implémentation Rails 8 + React

1. Générer le jeton CSRF sur le serveur

Configurez Rails pour générer un jeton CSRF et l’envoyer dans un cookie.

Dans app/controllers/application_controller.rb :

class ApplicationController < ActionController::API
  include ActionController::Cookies
  include ActionController::RequestForgeryProtection

  protect_from_forgery with: :exception
  before_action :set_csrf_cookie

  private

  def set_csrf_cookie
    cookies["CSRF-TOKEN"] = form_authenticity_token
  end
end

2. Utilisation du jeton CSRF dans React

Configurez les valeurs par défaut d’Axios dans src/axios.ts :

import axios from "axios";

axios.defaults.xsrfCookieName = "CSRF-TOKEN";
axios.defaults.xsrfHeaderName = "X-CSRF-Token";
axios.defaults.withCredentials = true;

export default axios;

Ensuite, dans votre composant :

import axios from "../axios";

export default function Register() {
  useEffect(() => {
    axios.get("api/csrf-token");
  }, []);

  function handleRegistration() {
    axios.post("api/users", { email, password });
  }

  return (
    // votre formulaire TSX
  );
}

Conclusion

Vous avez appris comment fonctionne le CSRF, pourquoi CORS seul ne l’empêche pas, et comment implémenter la protection CSRF dans Rails 8 avec un frontend React.