Skip to content

Instantly share code, notes, and snippets.

@csknk
Last active December 6, 2019 08:30
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save csknk/4e4adde53a9c54f94e25e8a72f1251e8 to your computer and use it in GitHub Desktop.
Save csknk/4e4adde53a9c54f94e25e8a72f1251e8 to your computer and use it in GitHub Desktop.
Set up CORS on a Laravel API to respond to an Axios request with an 'OPTIONS' preflight.
<?php
// routes/api.php
use Illuminate\Http\Request;
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
Route::post('/cart', 'Api\CartController@addProduct');
Route::options('/cart', function() { return; });
Route::get('/cart', 'Api\CartController@show');
Route::get('/products', 'Api\ProductsController@index');
Route::get('/products/{productID}', 'Api\ProductsController@show');
Route::delete('/cart/{productID}', 'Api\CartController@deleteProductFromCart');
// Respond to the Axios pre-flight check, which makes an OPTIONS request.
// A blank response body is sufficient - the CORS middleware builds the
// appropriate header.
Route::options('/cart/{productID}', function() { return; });
Route::delete('/cart', 'Api\CartController@deleteAllFromCart');
// ... You can also add a body to the OPTIONS response - some argue that
// this is more appropriate:
Route::options('/cart', function() {
$response = [
'methods-allowed' => ['POST', 'GET', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
'description' => 'Route to clear the shopping cart'
];
return json_encode($response);
});
<?php
// app/Http/Middleware/Cors.php
// It's possible to generate the file with artisan (see comment)
namespace App\Http\Middleware;
use Closure;
class Cors
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
return $next($request)
// For security, you should probably specify a URL:
// e.g. ->header('Access-Control-Allow-Origin', 'http://localhost:8080')
->header('Access-Control-Allow-Origin', '*')
->header('Access-Control-Allow-Headers', 'X-PINGOTHER, Content-Type, Authorization, Content-Length, X-Requested-With')
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS');
}
}
<?php
// app/Http/Kernel.php
// Note references to cors
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* @var array
*/
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
/**
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'cors',
'throttle:60,1',
'bindings',
],
];
/**
* The application's route middleware.
* @var array
*/
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'cors' => \App\Http\Middleware\Cors::class,
];
}
@csknk
Copy link
Author

csknk commented Aug 17, 2017

The files above set up CORS for an Axios request in Laravel 5.4.

From the OPTIONS spec:

Content negotiation MAY be used to select the appropriate response format. If no response body is included, the response MUST include a Content-Length field with a field-value of "0".

Artisan Command: Middleware

Make a blank middleware file for Cors:

php artisan make:middleware Cors

Resources

@jensysantana
Copy link

thank you. this really work.

@Abenezer01
Copy link

Its not working for me....i don't understand what the problem is.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment