redyk654
a posé

Laravel Sanctum authentification avec React

Bonjour. j'ai un pb avec l'authentification de sanctum. dans mon code LoginController je verifie les credentials puis si tout est bon je retourne le jeton d'Api

public function login(Request $request)
{
$credentials = $request->only(['email', 'password']);
 
if (Auth::attempt($credentials)) {
// Récupérer l'utilisateur authentifié
$user = Auth::user();
 
// Générer un jeton d'API pour l'utilisateur
// ...
$token = $user->createToken('Token Name')->plainTextToken;
 
// Retourner le token dans la réponse JSON
return response()->json(['token' => $token], 200);
} else {
return response()->json(['error' => 'Unauthorized'], 401);
}
}

et ici jái ma route vers le login

Route::post('v1/login', [LoginController::class, 'login']);

ici mon code React qui test l'auth

import axios from 'axios';
 
const csrfTokenElement = document.querySelector('meta[name="csrf-token"]');
const csrfToken = csrfTokenElement ? csrfTokenElement.getAttribute('content') : null;
 
axios.defaults.headers.common['X-CSRF-TOKEN'] = csrfToken || '';
 
// axios.defaults.withCredentials = true;
// axios.defaults.withXSRFToken = true;
 
export async function signInRequest (email: string, password: string) {
// console.log(email, password);
 
try {
const response = await axios.post(`http://localhost:8000/api/v1/login`, {
email,
password
});
 
console.log(response.data);
// localStorage.setItem('token', response.data.token);
} catch (error) {
console.error('Erreur lors de l\'authentification : ', error);
throw error;
}
}

le pb est que je lorsque je j'utilise la methode post ça ne marche pas j'ai une erreur de type : POST http://localhost:8000/api/v1/login 419 (unknown status) mais quand j'utilise get j'obtient bien mon token. mais pour des raisons de securité je dois use post donc j'aimerais comprendre qu'es ce qui peut causer cela ?

xdcondor
xdcondor 265 XP
a répondu

Bonjour toi, j'espère que tu vas bien!! L'erreur 419 survient généralement lorsque le jeton CSRF n'est pas posté ou soit celui-ci à expiré.

xdcondor
xdcondor 265 XP
a répondu

Maintenant dans ton cas tu utilises react donc tu n'as pas trop besoin du jeton CSRF ( à mon avis ). Tu dois plus tôt au niveau de ton front-end ( côté react) configurer axios pour qu’il envoie le cookie de session avec chaque requête. Ce qui permettra de déterminer l'utilisateur connecté à chaque requête.

redyk654
a répondu

En effet quand je consulte dans les tools du navigateur le jeton CSRF n'est pas dans le header de la requête. Mais comment je fais pour récupérer le cookie de session ? Puisque la première requête dauth

redyk654
a répondu

Me renvoie déjà une erreur

redyk654
a répondu
Meilleure réponse

j'ai resolu le problème en faisant ceci

export const signInRequest = (email: string, password: string) => {
// console.log(email, password);
 
axios.get('http://localhost:8000/sanctum/csrf-cookie').then(async (response) => {
// Login...
try {
const response = await axios.post('http://localhost:8000/api/v1/login', {
email,
password
});
 
// console.log(response.data);
getClientsRequest();
} catch (error) {
console.log((error as any).response.data.message);
}
});
 
}

en fait il fallait d'emblé faire une requete vers sanctum/csrf-cookie pour recuperer le cookie et le stocker (automatique avec axios) puis utiliser dans toutes les autres requêtes (c'est expliqué dans la doc). et dans mon controller j'utilise désormais un cookie de session

LoginController

public function login(Request $request)
{
$request->validate([
'email' => 'required|email',
'password' => 'required',
]);
 
if (Auth::attempt($request->only('email', 'password'))) {
$user = Auth::user();
$token = $user->createToken('login')->plainTextToken;
 
// Ajouter le cookie de session pour l'utilisateur authentifié
$cookie = cookie('token', $token, 15); // Durée de validité de 15 minutes
 
return response()->json(['token' => $token], 200)->withCookie($cookie);
}
 
throw ValidationException::withMessages([
'email' => ['The provided credentials are incorrect.'],
]);
}

Il faut Se connecter ou Créer un compte pour participer à cette conversation.