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

<?php
 
namespace App\Http\Middleware;
 
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
 
class CorsMiddleware
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next)
{
$response = $next($request);
 
$response->headers->set('Access-Control-Allow-Origin', $request->header('Origin'));
$response->headers->set('Access-Control-Allow-Methods', ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']);
$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']);
$response->headers->set('Access-Control-Allow-Credentials', 'true');
 
return $response;
}
}

config/cors

<?php
 
return [
 
/*
|--------------------------------------------------------------------------
| Cross-Origin Resource Sharing (CORS) Configuration
|--------------------------------------------------------------------------
|
| Here you may configure your settings for cross-origin resource sharing
| or "CORS". This determines what cross-origin operations may execute
| in web browsers. You are free to adjust these settings as needed.
|
|
*/
 
'paths' => ['api/*', 'sanctum/csrf-cookie'],
 
'allowed_methods' => ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
 
'allowed_origins' => ['*'],
 
'allowed_origins_patterns' => [],
 
'allowed_headers' => [
'Content-Type',
'X-Auth-Token',
'Authorization',
'Accept',
'X-Requested-With',
'Access-Control-Request-Method',
'Access-Control-Request-Headers',
'X-CSRF-TOKEN'
],
 
'exposed_headers' => [],
 
'max_age' => 0,
 
'supports_credentials' => true,
 
];

bootstrap/app

<?php
 
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
 
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
api: __DIR__.'/../routes/api.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
$middleware->append(\App\Http\Middleware\CorsMiddleware::class);
})
->withExceptions(function (Exceptions $exceptions) {
//
})->create();

api.php

Route::middleware('auth:api')->group(function () {
// Customers
Route::prefix('clients')->group(function () {
Route::get('/', [Api\ClientController::class, 'index']);
// Others Routes
});
// Suppliers
Route::prefix('suppliers')->group(function () {
Route::get('/', [Api\FournisseurController::class, 'index']);
// Others Routes
});
 
Route::prefix('products')->group(function () {
Route::get('/', [Api\ProductController::class, 'index']);
// Others Routes
});
 
Route::prefix('invoices')->group(function () {
Route::get('/', [Api\InvoiceController::class, 'index']);
// Others routes
});
 
Route::prefix('orders')->group(function () {
Route::get('/', [Api\CommandController::class, 'index']);
// Others routes
});
});

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

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

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

darwin_nathan
a répondu

Celles qui echouent sont celles laisses plus haut dans le code

Route::middleware('auth:api')->group(function () {
// Users
Route::prefix('user')->group(function () {
Route::get('/', [Api\AuthController::class, 'me']);
Route::post('/logout', [Api\AuthController::class, 'logout']);
Route::put('update-profile', [Api\UserController::class, 'update']);
Route::delete('delete-account', [Api\UserController::class, 'delete']);
});
// Customers
Route::prefix('clients')->group(function () {
Route::get('/', [Api\ClientController::class, 'index']);
Route::get('/{id}', [Api\ClientController::class, 'show']);
Route::post('/create', [Api\ClientController::class, 'create']);
Route::put('/update/{id}', [Api\ClientController::class, 'update']);
Route::delete('/delete/{id}', [Api\ClientController::class, 'destroy']);
});
// Suppliers
Route::prefix('suppliers')->group(function () {
Route::get('/', [Api\FournisseurController::class, 'index']);
Route::get('/{id}', [Api\FournisseurController::class, 'show']);
Route::post('/{id}', [Api\FournisseurController::class, 'attachProduct']);
Route::post('/create', [Api\FournisseurController::class, 'store']);
Route::put('/update/{id}', [Api\FournisseurController::class, 'update']);
Route::delete('/delete/{id}', [Api\FournisseurController::class, 'destroy']);
});
 
Route::prefix('products')->group(function () {
Route::get('/', [Api\ProductController::class, 'index']);
Route::get('/{id}', [Api\ProductController::class, 'show']);
Route::post('/create', [Api\ProductController::class, 'store']);
Route::put('/update/{id}', [Api\ProductController::class, 'update']);
Route::delete('/delete/{id}', [Api\ProductController::class, 'destroy']);
});
 
Route::prefix('invoices')->group(function () {
Route::get('/', [Api\InvoiceController::class, 'index']);
Route::get('/{id}', [Api\InvoiceController::class, 'show']);
Route::post('/create', [Api\InvoiceController::class, 'store']);
Route::put('/update/{id}', [Api\InvoiceController::class, 'update']);
Route::delete('/delete/{id}', [Api\InvoiceController::class, 'destroy']);
Route::post('/pay', [Api\PaymentController::class, 'payForInvoice']);
});
 
Route::prefix('payments')->group(function () {
Route::get('/{id}', [Api\PaymentController::class, 'show']);
Route::delete('/delete/{id}', [Api\PaymentController::class, 'destroy']);
});
 
Route::prefix('orders')->group(function () {
Route::get('/', [Api\CommandController::class, 'index']);
Route::get('/{id}', [Api\CommandController::class, 'show']);
Route::post('/create', [Api\CommandController::class, 'create']);
Route::put('/update/{id}', [Api\CommandController::class, 'update']);
Route::delete('/delete/{id}', [Api\CommandController::class, 'destroy']);
Route::post('/pay', [Api\PaymentController::class, 'payForOrder']);
});
 
Route::prefix('dashboard')->group(function () {
Route::get('/stats', [Api\DashboardController::class, 'stats']);
});
});

Juste les routes index

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

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

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

$response = $next($request);

je pense que tu peux directement faire ceci sur $request

$request->headers->set('Access-Control-Allow-Origin', $request->header('Origin'));
darwin_nathan
a répondu

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

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 .

darwin_nathan
a répondu

Oui

stevymarlino
a répondu

Salut @darwin_nathan

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

darwin_nathan
a répondu

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

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

darwin_nathan
a répondu

Voila tout

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