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.