darwin_nathan
a posé

Probleme de Cors sur Laravel 11.

J'ai termine avec un projet en api. Mais en prod je me rends compte que certaines requetes (pas toutes) echouaient avec l'erreur CORS failed dans l'onglet reseau du navigateur. J'ai fais le php artisan config:publish cors. Que je le laisse comme predefini ou meme que je le configure j'obtiens des erreurs sur ces routes. J'ai cree un middleware pour gerer le CORS ensuite et malgre cela aucune solution apparente. Middleware

1<?php
2 
3namespace App\Http\Middleware;
4 
5use Closure;
6use Illuminate\Http\Request;
7use Symfony\Component\HttpFoundation\Response;
8 
9class CorsMiddleware
10{
11 /**
12 * Handle an incoming request.
13 *
14 * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
15 */
16 public function handle(Request $request, Closure $next)
17 {
18 $response = $next($request);
19 
20 $response->headers->set('Access-Control-Allow-Origin', $request->header('Origin'));
21 $response->headers->set('Access-Control-Allow-Methods', ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']);
22 $response->headers->set('Access-Control-Allow-Headers', ['Content-Type', 'X-Auth-Token', 'Authorization', 'Accept', 'X-Requested-With', 'Access-Control-Request-Method', 'Access-Control-Request-Headers', 'X-CSRF-TOKEN']);
23 $response->headers->set('Access-Control-Allow-Credentials', 'true');
24 
25 return $response;
26 }
27}
1<?php
2 
3namespace App\Http\Middleware;
4 
5use Closure;
6use Illuminate\Http\Request;
7use Symfony\Component\HttpFoundation\Response;
8 
9class CorsMiddleware
10{
11 /**
12 * Handle an incoming request.
13 *
14 * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
15 */
16 public function handle(Request $request, Closure $next)
17 {
18 $response = $next($request);
19 
20 $response->headers->set('Access-Control-Allow-Origin', $request->header('Origin'));
21 $response->headers->set('Access-Control-Allow-Methods', ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']);
22 $response->headers->set('Access-Control-Allow-Headers', ['Content-Type', 'X-Auth-Token', 'Authorization', 'Accept', 'X-Requested-With', 'Access-Control-Request-Method', 'Access-Control-Request-Headers', 'X-CSRF-TOKEN']);
23 $response->headers->set('Access-Control-Allow-Credentials', 'true');
24 
25 return $response;
26 }
27}

config/cors

1<?php
2 
3return [
4 
5 /*
6 |--------------------------------------------------------------------------
7 | Cross-Origin Resource Sharing (CORS) Configuration
8 |--------------------------------------------------------------------------
9 |
10 | Here you may configure your settings for cross-origin resource sharing
11 | or "CORS". This determines what cross-origin operations may execute
12 | in web browsers. You are free to adjust these settings as needed.
13 |
15 |
16 */
17 
18 'paths' => ['api/*', 'sanctum/csrf-cookie'],
19 
20 'allowed_methods' => ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
21 
22 'allowed_origins' => ['*'],
23 
24 'allowed_origins_patterns' => [],
25 
26 'allowed_headers' => [
27 'Content-Type',
28 'X-Auth-Token',
29 'Authorization',
30 'Accept',
31 'X-Requested-With',
32 'Access-Control-Request-Method',
33 'Access-Control-Request-Headers',
34 'X-CSRF-TOKEN'
35 ],
36 
37 'exposed_headers' => [],
38 
39 'max_age' => 0,
40 
41 'supports_credentials' => true,
42 
43];
1<?php
2 
3return [
4 
5 /*
6 |--------------------------------------------------------------------------
7 | Cross-Origin Resource Sharing (CORS) Configuration
8 |--------------------------------------------------------------------------
9 |
10 | Here you may configure your settings for cross-origin resource sharing
11 | or "CORS". This determines what cross-origin operations may execute
12 | in web browsers. You are free to adjust these settings as needed.
13 |
15 |
16 */
17 
18 'paths' => ['api/*', 'sanctum/csrf-cookie'],
19 
20 'allowed_methods' => ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
21 
22 'allowed_origins' => ['*'],
23 
24 'allowed_origins_patterns' => [],
25 
26 'allowed_headers' => [
27 'Content-Type',
28 'X-Auth-Token',
29 'Authorization',
30 'Accept',
31 'X-Requested-With',
32 'Access-Control-Request-Method',
33 'Access-Control-Request-Headers',
34 'X-CSRF-TOKEN'
35 ],
36 
37 'exposed_headers' => [],
38 
39 'max_age' => 0,
40 
41 'supports_credentials' => true,
42 
43];

bootstrap/app

1<?php
2 
3use Illuminate\Foundation\Application;
4use Illuminate\Foundation\Configuration\Exceptions;
5use Illuminate\Foundation\Configuration\Middleware;
6 
7return Application::configure(basePath: dirname(__DIR__))
8 ->withRouting(
9 web: __DIR__.'/../routes/web.php',
10 api: __DIR__.'/../routes/api.php',
11 commands: __DIR__.'/../routes/console.php',
12 health: '/up',
13 )
14 ->withMiddleware(function (Middleware $middleware) {
15 $middleware->append(\App\Http\Middleware\CorsMiddleware::class);
16 })
17 ->withExceptions(function (Exceptions $exceptions) {
18 //
19 })->create();
1<?php
2 
3use Illuminate\Foundation\Application;
4use Illuminate\Foundation\Configuration\Exceptions;
5use Illuminate\Foundation\Configuration\Middleware;
6 
7return Application::configure(basePath: dirname(__DIR__))
8 ->withRouting(
9 web: __DIR__.'/../routes/web.php',
10 api: __DIR__.'/../routes/api.php',
11 commands: __DIR__.'/../routes/console.php',
12 health: '/up',
13 )
14 ->withMiddleware(function (Middleware $middleware) {
15 $middleware->append(\App\Http\Middleware\CorsMiddleware::class);
16 })
17 ->withExceptions(function (Exceptions $exceptions) {
18 //
19 })->create();

api.php

1Route::middleware('auth:api')->group(function () {
2 // Customers
3 Route::prefix('clients')->group(function () {
4 Route::get('/', [Api\ClientController::class, 'index']);
5 // Others Routes
6 });
7 // Suppliers
8 Route::prefix('suppliers')->group(function () {
9 Route::get('/', [Api\FournisseurController::class, 'index']);
10 // Others Routes
11 });
12 
13 Route::prefix('products')->group(function () {
14 Route::get('/', [Api\ProductController::class, 'index']);
15 // Others Routes
16 });
17 
18 Route::prefix('invoices')->group(function () {
19 Route::get('/', [Api\InvoiceController::class, 'index']);
20 // Others routes
21 });
22 
23 Route::prefix('orders')->group(function () {
24 Route::get('/', [Api\CommandController::class, 'index']);
25 // Others routes
26 });
27});
1Route::middleware('auth:api')->group(function () {
2 // Customers
3 Route::prefix('clients')->group(function () {
4 Route::get('/', [Api\ClientController::class, 'index']);
5 // Others Routes
6 });
7 // Suppliers
8 Route::prefix('suppliers')->group(function () {
9 Route::get('/', [Api\FournisseurController::class, 'index']);
10 // Others Routes
11 });
12 
13 Route::prefix('products')->group(function () {
14 Route::get('/', [Api\ProductController::class, 'index']);
15 // Others Routes
16 });
17 
18 Route::prefix('invoices')->group(function () {
19 Route::get('/', [Api\InvoiceController::class, 'index']);
20 // Others routes
21 });
22 
23 Route::prefix('orders')->group(function () {
24 Route::get('/', [Api\CommandController::class, 'index']);
25 // Others routes
26 });
27});

A preciser: Aucun souci en dev, et aucune erreur sur postman en prod.

mckenziearts
a répondu

Dans ton fichier routes/api.php quelles sont les routes qui échouent en ligne ? Et quand tu écris du code faut préciser le langage pour avoir la couleur syntaxique

1Route::prefix('products')->group(function () {
2 Route::get('/', [Api\ProductController::class, 'index']);
3 // Others Routes
4});
1Route::prefix('products')->group(function () {
2 Route::get('/', [Api\ProductController::class, 'index']);
3 // Others Routes
4});

Faut rajouter le language après les ```php

Confirmer la suppression

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

darwin_nathan
a répondu

Celles qui echouent sont celles laisses plus haut dans le code

1Route::middleware('auth:api')->group(function () {
2 // Users
3 Route::prefix('user')->group(function () {
4 Route::get('/', [Api\AuthController::class, 'me']);
5 Route::post('/logout', [Api\AuthController::class, 'logout']);
6 Route::put('update-profile', [Api\UserController::class, 'update']);
7 Route::delete('delete-account', [Api\UserController::class, 'delete']);
8 });
9 // Customers
10 Route::prefix('clients')->group(function () {
11 Route::get('/', [Api\ClientController::class, 'index']);
12 Route::get('/{id}', [Api\ClientController::class, 'show']);
13 Route::post('/create', [Api\ClientController::class, 'create']);
14 Route::put('/update/{id}', [Api\ClientController::class, 'update']);
15 Route::delete('/delete/{id}', [Api\ClientController::class, 'destroy']);
16 });
17 // Suppliers
18 Route::prefix('suppliers')->group(function () {
19 Route::get('/', [Api\FournisseurController::class, 'index']);
20 Route::get('/{id}', [Api\FournisseurController::class, 'show']);
21 Route::post('/{id}', [Api\FournisseurController::class, 'attachProduct']);
22 Route::post('/create', [Api\FournisseurController::class, 'store']);
23 Route::put('/update/{id}', [Api\FournisseurController::class, 'update']);
24 Route::delete('/delete/{id}', [Api\FournisseurController::class, 'destroy']);
25 });
26 
27 Route::prefix('products')->group(function () {
28 Route::get('/', [Api\ProductController::class, 'index']);
29 Route::get('/{id}', [Api\ProductController::class, 'show']);
30 Route::post('/create', [Api\ProductController::class, 'store']);
31 Route::put('/update/{id}', [Api\ProductController::class, 'update']);
32 Route::delete('/delete/{id}', [Api\ProductController::class, 'destroy']);
33 });
34 
35 Route::prefix('invoices')->group(function () {
36 Route::get('/', [Api\InvoiceController::class, 'index']);
37 Route::get('/{id}', [Api\InvoiceController::class, 'show']);
38 Route::post('/create', [Api\InvoiceController::class, 'store']);
39 Route::put('/update/{id}', [Api\InvoiceController::class, 'update']);
40 Route::delete('/delete/{id}', [Api\InvoiceController::class, 'destroy']);
41 Route::post('/pay', [Api\PaymentController::class, 'payForInvoice']);
42 });
43 
44 Route::prefix('payments')->group(function () {
45 Route::get('/{id}', [Api\PaymentController::class, 'show']);
46 Route::delete('/delete/{id}', [Api\PaymentController::class, 'destroy']);
47 });
48 
49 Route::prefix('orders')->group(function () {
50 Route::get('/', [Api\CommandController::class, 'index']);
51 Route::get('/{id}', [Api\CommandController::class, 'show']);
52 Route::post('/create', [Api\CommandController::class, 'create']);
53 Route::put('/update/{id}', [Api\CommandController::class, 'update']);
54 Route::delete('/delete/{id}', [Api\CommandController::class, 'destroy']);
55 Route::post('/pay', [Api\PaymentController::class, 'payForOrder']);
56 });
57 
58 Route::prefix('dashboard')->group(function () {
59 Route::get('/stats', [Api\DashboardController::class, 'stats']);
60 });
61});
1Route::middleware('auth:api')->group(function () {
2 // Users
3 Route::prefix('user')->group(function () {
4 Route::get('/', [Api\AuthController::class, 'me']);
5 Route::post('/logout', [Api\AuthController::class, 'logout']);
6 Route::put('update-profile', [Api\UserController::class, 'update']);
7 Route::delete('delete-account', [Api\UserController::class, 'delete']);
8 });
9 // Customers
10 Route::prefix('clients')->group(function () {
11 Route::get('/', [Api\ClientController::class, 'index']);
12 Route::get('/{id}', [Api\ClientController::class, 'show']);
13 Route::post('/create', [Api\ClientController::class, 'create']);
14 Route::put('/update/{id}', [Api\ClientController::class, 'update']);
15 Route::delete('/delete/{id}', [Api\ClientController::class, 'destroy']);
16 });
17 // Suppliers
18 Route::prefix('suppliers')->group(function () {
19 Route::get('/', [Api\FournisseurController::class, 'index']);
20 Route::get('/{id}', [Api\FournisseurController::class, 'show']);
21 Route::post('/{id}', [Api\FournisseurController::class, 'attachProduct']);
22 Route::post('/create', [Api\FournisseurController::class, 'store']);
23 Route::put('/update/{id}', [Api\FournisseurController::class, 'update']);
24 Route::delete('/delete/{id}', [Api\FournisseurController::class, 'destroy']);
25 });
26 
27 Route::prefix('products')->group(function () {
28 Route::get('/', [Api\ProductController::class, 'index']);
29 Route::get('/{id}', [Api\ProductController::class, 'show']);
30 Route::post('/create', [Api\ProductController::class, 'store']);
31 Route::put('/update/{id}', [Api\ProductController::class, 'update']);
32 Route::delete('/delete/{id}', [Api\ProductController::class, 'destroy']);
33 });
34 
35 Route::prefix('invoices')->group(function () {
36 Route::get('/', [Api\InvoiceController::class, 'index']);
37 Route::get('/{id}', [Api\InvoiceController::class, 'show']);
38 Route::post('/create', [Api\InvoiceController::class, 'store']);
39 Route::put('/update/{id}', [Api\InvoiceController::class, 'update']);
40 Route::delete('/delete/{id}', [Api\InvoiceController::class, 'destroy']);
41 Route::post('/pay', [Api\PaymentController::class, 'payForInvoice']);
42 });
43 
44 Route::prefix('payments')->group(function () {
45 Route::get('/{id}', [Api\PaymentController::class, 'show']);
46 Route::delete('/delete/{id}', [Api\PaymentController::class, 'destroy']);
47 });
48 
49 Route::prefix('orders')->group(function () {
50 Route::get('/', [Api\CommandController::class, 'index']);
51 Route::get('/{id}', [Api\CommandController::class, 'show']);
52 Route::post('/create', [Api\CommandController::class, 'create']);
53 Route::put('/update/{id}', [Api\CommandController::class, 'update']);
54 Route::delete('/delete/{id}', [Api\CommandController::class, 'destroy']);
55 Route::post('/pay', [Api\PaymentController::class, 'payForOrder']);
56 });
57 
58 Route::prefix('dashboard')->group(function () {
59 Route::get('/stats', [Api\DashboardController::class, 'stats']);
60 });
61});

Juste les routes index

Confirmer la suppression

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

russeloken
a répondu

Le probleme vient du faite que tes CORS ne sont pas ajoutés avant auth:api

Dans ton fichier bootstrap/app essaie plutot

1->withMiddleware(function (Middleware $middleware) {
2 $middleware->prepend(\App\Http\Middleware\CorsMiddleware::class);
3})
1->withMiddleware(function (Middleware $middleware) {
2 $middleware->prepend(\App\Http\Middleware\CorsMiddleware::class);
3})

Tu dois utiliser prepend() au lieu de append() pour forcer Laravel à exécuter le middleware CORS avant auth:api

Par la suite tu vides le cache

Bon je me demande pourquoi dans ton middleware tu fais

1$response = $next($request);
1$response = $next($request);

je pense que tu peux directement faire ceci sur $request

1$request->headers->set('Access-Control-Allow-Origin', $request->header('Origin'));
1$request->headers->set('Access-Control-Allow-Origin', $request->header('Origin'));
Confirmer la suppression

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

lelouch_p
a répondu

Les configs que tu as presenter sont les configs de prod ? Fais voir le header de la requete du navigateur .

Confirmer la suppression

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

darwin_nathan
a répondu

Oui

Confirmer la suppression

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

stevymarlino
a répondu

Salut @darwin_nathan

1SANCTUM_STATEFUL_DOMAINS=http://127.0.0.1:8000
1SANCTUM_STATEFUL_DOMAINS=http://127.0.0.1:8000

dans ton api essaie de mettre cette ligne, elle represente le domaine principale pour contacter ton api.

Confirmer la suppression

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

darwin_nathan
a répondu

Le souci n'est pas en dev. Mais plutot en prod.

Confirmer la suppression

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

mckenziearts
a répondu

J'ai l'impression que ce sont les requests en POST, PUT qui foirent ? Mais après quand je vois le type de données que tu reçcois ça je sais pas si c'est normal. Essaie un peu de montre les headers de la requete /api/products la pour voir ce qu'il y'a dans les headers

Confirmer la suppression

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

darwin_nathan
a répondu

Voila tout

Confirmer la suppression

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

darwin_nathan
a répondu

@russeloken, merci mais cela n'a pas fonctionne. Je sais pas pourquoi mais ca ne marche toujours pas

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.