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

1public function login(Request $request)
2{
3 $credentials = $request->only(['email', 'password']);
4 
5 if (Auth::attempt($credentials)) {
6 // Récupérer l'utilisateur authentifié
7 $user = Auth::user();
8 
9 // Générer un jeton d'API pour l'utilisateur
10 // ...
11 $token = $user->createToken('Token Name')->plainTextToken;
12 
13 // Retourner le token dans la réponse JSON
14 return response()->json(['token' => $token], 200);
15 } else {
16 return response()->json(['error' => 'Unauthorized'], 401);
17 }
18}
1public function login(Request $request)
2{
3 $credentials = $request->only(['email', 'password']);
4 
5 if (Auth::attempt($credentials)) {
6 // Récupérer l'utilisateur authentifié
7 $user = Auth::user();
8 
9 // Générer un jeton d'API pour l'utilisateur
10 // ...
11 $token = $user->createToken('Token Name')->plainTextToken;
12 
13 // Retourner le token dans la réponse JSON
14 return response()->json(['token' => $token], 200);
15 } else {
16 return response()->json(['error' => 'Unauthorized'], 401);
17 }
18}

et ici jái ma route vers le login

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

ici mon code React qui test l'auth

1import axios from 'axios';
2 
3const csrfTokenElement = document.querySelector('meta[name="csrf-token"]');
4const csrfToken = csrfTokenElement ? csrfTokenElement.getAttribute('content') : null;
5 
6axios.defaults.headers.common['X-CSRF-TOKEN'] = csrfToken || '';
7 
8// axios.defaults.withCredentials = true;
9// axios.defaults.withXSRFToken = true;
10 
11export async function signInRequest (email: string, password: string) {
12 // console.log(email, password);
13 
14 try {
15 const response = await axios.post(`http://localhost:8000/api/v1/login`, {
16 email,
17 password
18 });
19 
20 console.log(response.data);
21 // localStorage.setItem('token', response.data.token);
22 } catch (error) {
23 console.error('Erreur lors de l\'authentification : ', error);
24 throw error;
25 }
26}
1import axios from 'axios';
2 
3const csrfTokenElement = document.querySelector('meta[name="csrf-token"]');
4const csrfToken = csrfTokenElement ? csrfTokenElement.getAttribute('content') : null;
5 
6axios.defaults.headers.common['X-CSRF-TOKEN'] = csrfToken || '';
7 
8// axios.defaults.withCredentials = true;
9// axios.defaults.withXSRFToken = true;
10 
11export async function signInRequest (email: string, password: string) {
12 // console.log(email, password);
13 
14 try {
15 const response = await axios.post(`http://localhost:8000/api/v1/login`, {
16 email,
17 password
18 });
19 
20 console.log(response.data);
21 // localStorage.setItem('token', response.data.token);
22 } catch (error) {
23 console.error('Erreur lors de l\'authentification : ', error);
24 throw error;
25 }
26}

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é.

Confirmer la suppression

Êtes-vous sûr de vouloir supprimer cette réponse ? Cette action est irréversible.

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.

Confirmer la suppression

Êtes-vous sûr de vouloir supprimer cette réponse ? Cette action est irréversible.

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

Confirmer la suppression

Êtes-vous sûr de vouloir supprimer cette réponse ? Cette action est irréversible.

redyk654
a répondu

Me renvoie déjà une erreur

Confirmer la suppression

Êtes-vous sûr de vouloir supprimer cette réponse ? Cette action est irréversible.

redyk654
a répondu
Meilleure réponse

j'ai resolu le problème en faisant ceci

1export const signInRequest = (email: string, password: string) => {
2 // console.log(email, password);
3 
4 axios.get('http://localhost:8000/sanctum/csrf-cookie').then(async (response) => {
5 // Login...
6 try {
7 const response = await axios.post('http://localhost:8000/api/v1/login', {
8 email,
9 password
10 });
11 
12 // console.log(response.data);
13 getClientsRequest();
14 } catch (error) {
15 console.log((error as any).response.data.message);
16 }
17 });
18 
19}
1export const signInRequest = (email: string, password: string) => {
2 // console.log(email, password);
3 
4 axios.get('http://localhost:8000/sanctum/csrf-cookie').then(async (response) => {
5 // Login...
6 try {
7 const response = await axios.post('http://localhost:8000/api/v1/login', {
8 email,
9 password
10 });
11 
12 // console.log(response.data);
13 getClientsRequest();
14 } catch (error) {
15 console.log((error as any).response.data.message);
16 }
17 });
18 
19}

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

1public function login(Request $request)
2{
3 $request->validate([
4 'email' => 'required|email',
5 'password' => 'required',
6 ]);
7 
8 if (Auth::attempt($request->only('email', 'password'))) {
9 $user = Auth::user();
10 $token = $user->createToken('login')->plainTextToken;
11 
12 // Ajouter le cookie de session pour l'utilisateur authentifié
13 $cookie = cookie('token', $token, 15); // Durée de validité de 15 minutes
14 
15 return response()->json(['token' => $token], 200)->withCookie($cookie);
16 }
17 
18 throw ValidationException::withMessages([
19 'email' => ['The provided credentials are incorrect.'],
20 ]);
21}
1public function login(Request $request)
2{
3 $request->validate([
4 'email' => 'required|email',
5 'password' => 'required',
6 ]);
7 
8 if (Auth::attempt($request->only('email', 'password'))) {
9 $user = Auth::user();
10 $token = $user->createToken('login')->plainTextToken;
11 
12 // Ajouter le cookie de session pour l'utilisateur authentifié
13 $cookie = cookie('token', $token, 15); // Durée de validité de 15 minutes
14 
15 return response()->json(['token' => $token], 200)->withCookie($cookie);
16 }
17 
18 throw ValidationException::withMessages([
19 'email' => ['The provided credentials are incorrect.'],
20 ]);
21}
Confirmer la suppression

Êtes-vous sûr de vouloir supprimer cette réponse ? Cette action est irréversible.

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

Confirmer la suppression

Êtes-vous sûr de vouloir supprimer ce sujet ? Cette action est irréversible.