darwin_nathan
asked

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
posted

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

Confirm deletion

Are you sure you want to delete this reply? This action is irreversible.

darwin_nathan
posted

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

Confirm deletion

Are you sure you want to delete this reply? This action is irreversible.

russeloken
posted

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'));
Confirm deletion

Are you sure you want to delete this reply? This action is irreversible.

lelouch_p
posted

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

Confirm deletion

Are you sure you want to delete this reply? This action is irreversible.

darwin_nathan
posted

Oui

Confirm deletion

Are you sure you want to delete this reply? This action is irreversible.

stevymarlino
posted

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.

Confirm deletion

Are you sure you want to delete this reply? This action is irreversible.

darwin_nathan
posted

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

Confirm deletion

Are you sure you want to delete this reply? This action is irreversible.

mckenziearts
posted

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

Confirm deletion

Are you sure you want to delete this reply? This action is irreversible.

darwin_nathan
posted

Voila tout

Confirm deletion

Are you sure you want to delete this reply? This action is irreversible.

darwin_nathan
posted

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

Confirm deletion

Are you sure you want to delete this reply? This action is irreversible.

You need Log in or Create an account to join the conversation.

Confirm deletion

Are you sure you want to delete this thread? This action is irreversible.