Laravel 5.1 API Enable Cors
Solution 1
Here is my CORS middleware:
<?php 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)
{
header("Access-Control-Allow-Origin: *");
// ALLOW OPTIONS METHOD
$headers = [
'Access-Control-Allow-Methods'=> 'POST, GET, OPTIONS, PUT, DELETE',
'Access-Control-Allow-Headers'=> 'Content-Type, X-Auth-Token, Origin'
];
if($request->getMethod() == "OPTIONS") {
// The client-side application can set only headers allowed in Access-Control-Allow-Headers
return Response::make('OK', 200, $headers);
}
$response = $next($request);
foreach($headers as $key => $value)
$response->header($key, $value);
return $response;
}
}
To use CORS middleware you have to register it first in your app\Http\Kernel.php file like this:
protected $routeMiddleware = [
//other middlewares
'cors' => 'App\Http\Middleware\CORS',
];
Then you can use it in your routes
Route::get('example', array('middleware' => 'cors', 'uses' => 'ExampleController@dummy'));
Edit: In Laravel ^8.0 you have to import the namespace of the controller and use the class like this:
use App\Http\Controllers\ExampleController;
Route::get('example', [ExampleController::class, 'dummy'])->middleware('cors');
Solution 2
I always use an easy method. Just add below lines to \public\index.php
file. You don't have to use a middleware I think.
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
Solution 3
I am using Laravel 5.4 and unfortunately although the accepted answer seems fine, for preflighted requests (like PUT
and DELETE
) which will be preceded by an OPTIONS
request, specifying the middleware in the $routeMiddleware
array (and using that in the routes definition file) will not work unless you define a route handler for OPTIONS
as well. This is because without an OPTIONS
route Laravel will internally respond to that method without the CORS headers.
So in short either define the middleware in the $middleware
array which runs globally for all requests or if you're doing it in $middlewareGroups
or $routeMiddleware
then also define a route handler for OPTIONS
. This can be done like this:
Route::match(['options', 'put'], '/route', function () {
// This will work with the middleware shown in the accepted answer
})->middleware('cors');
I also wrote a middleware for the same purpose which looks similar but is larger in size as it tries to be more configurable and handles a bunch of conditions as well:
<?php
namespace App\Http\Middleware;
use Closure;
class Cors
{
private static $allowedOriginsWhitelist = [
'http://localhost:8000'
];
// All the headers must be a string
private static $allowedOrigin = '*';
private static $allowedMethods = 'OPTIONS, GET, POST, PUT, PATCH, DELETE';
private static $allowCredentials = 'true';
private static $allowedHeaders = '';
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if (! $this->isCorsRequest($request))
{
return $next($request);
}
static::$allowedOrigin = $this->resolveAllowedOrigin($request);
static::$allowedHeaders = $this->resolveAllowedHeaders($request);
$headers = [
'Access-Control-Allow-Origin' => static::$allowedOrigin,
'Access-Control-Allow-Methods' => static::$allowedMethods,
'Access-Control-Allow-Headers' => static::$allowedHeaders,
'Access-Control-Allow-Credentials' => static::$allowCredentials,
];
// For preflighted requests
if ($request->getMethod() === 'OPTIONS')
{
return response('', 200)->withHeaders($headers);
}
$response = $next($request)->withHeaders($headers);
return $response;
}
/**
* Incoming request is a CORS request if the Origin
* header is set and Origin !== Host
*
* @param \Illuminate\Http\Request $request
*/
private function isCorsRequest($request)
{
$requestHasOrigin = $request->headers->has('Origin');
if ($requestHasOrigin)
{
$origin = $request->headers->get('Origin');
$host = $request->getSchemeAndHttpHost();
if ($origin !== $host)
{
return true;
}
}
return false;
}
/**
* Dynamic resolution of allowed origin since we can't
* pass multiple domains to the header. The appropriate
* domain is set in the Access-Control-Allow-Origin header
* only if it is present in the whitelist.
*
* @param \Illuminate\Http\Request $request
*/
private function resolveAllowedOrigin($request)
{
$allowedOrigin = static::$allowedOrigin;
// If origin is in our $allowedOriginsWhitelist
// then we send that in Access-Control-Allow-Origin
$origin = $request->headers->get('Origin');
if (in_array($origin, static::$allowedOriginsWhitelist))
{
$allowedOrigin = $origin;
}
return $allowedOrigin;
}
/**
* Take the incoming client request headers
* and return. Will be used to pass in Access-Control-Allow-Headers
*
* @param \Illuminate\Http\Request $request
*/
private function resolveAllowedHeaders($request)
{
$allowedHeaders = $request->headers->get('Access-Control-Request-Headers');
return $allowedHeaders;
}
}
Also written a blog post on this.
Solution 4
barryvdh/laravel-cors works perfectly with Laravel 5.1 with just a few key points in enabling it.
-
After adding it as a composer dependency, make sure you have published the CORS config file and adjusted the CORS headers as you want them. Here is how mine look in app/config/cors.php
<?php return [ 'supportsCredentials' => true, 'allowedOrigins' => ['*'], 'allowedHeaders' => ['*'], 'allowedMethods' => ['GET', 'POST', 'PUT', 'DELETE'], 'exposedHeaders' => ['DAV', 'content-length', 'Allow'], 'maxAge' => 86400, 'hosts' => [], ];
-
After this, there is one more step that's not mentioned in the documentation, you have to add the CORS handler
'Barryvdh\Cors\HandleCors'
in the App kernel. I prefer to use it in the global middleware stack. Like this/** * The application's global HTTP middleware stack. * * @var array */ protected $middleware = [ 'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode', 'Illuminate\Cookie\Middleware\EncryptCookies', 'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse', 'Illuminate\Session\Middleware\StartSession', 'Illuminate\View\Middleware\ShareErrorsFromSession', 'Barryvdh\Cors\HandleCors', ];
But its up to you to use it as a route middleware and place on specific routes.
This should make the package work with L5.1
Solution 5
For me i put this codes in public\index.php
file. and it worked just fine for all CRUD operations.
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS, post, get');
header("Access-Control-Max-Age", "3600");
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');
header("Access-Control-Allow-Credentials", "true");
Related videos on Youtube
Leonardo Lobato
Updated on November 13, 2021Comments
-
Leonardo Lobato over 2 years
I've looked for some ways to enable cors on laravel 5.1 specifically, I have found some libs like:
https://github.com/neomerx/cors-illuminate
https://github.com/barryvdh/laravel-cors
but none of them has a implementation tutorial specifically to Laravel 5.1, I tried to config but It doesn't work.
If someone already implemented CORS on laravel 5.1 I would be grateful for the help...
-
rdiz over 8 yearsBarryvdh's is for Laravel 5, and really it should work out of the box with 5.1 as well. Did you try it?
-
Leonardo Lobato over 8 yearsYes I tried, but I still getting the following message ( it's a angular frontend) XMLHttpRequest cannot load api.address.com. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '127.0.0.1:8080' is therefore not allowed access. But I have already added the local address on the cors files 'supportsCredentials' => true, 'allowedOrigins' => ['127.0.0.1:8080'], 'allowedHeaders' => ['*'], 'allowedMethods' => ['GET', 'POST', 'PUT', 'DELETE'], 'exposedHeaders' => [], 'maxAge' => 0, 'hosts' => [],
-
rdiz over 8 yearsWhich message do you get?
-
Leonardo Lobato over 8 yearsXMLHttpRequest cannot load api.address.com. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '127.0.0.1:8080'; is therefore not allowed access
-
rdiz over 8 yearsDid you publish the config file and edit it accordingly?
-
Kjell over 8 yearsDid you have a look at the response header in your browser? There the Access-Control-Allow-Origin header should be set to the right domain. Also you could try to set it yourself on one route "by hand"...
-
Leonardo Lobato over 8 yearsAccess-Control-Allow-Credentials → true Access-Control-Allow-Headers → Origin, Content-Type, Accept, Authorization, X-Request-With Access-Control-Allow-Methods → GET, POST, OPTIONS Access-Control-Allow-Origin → * The cors seems to woking, I already tried my localhost instead of * but still don't working
-
-
suncoastkid over 8 yearsWorks on Apache but not IIS :(
-
retrograde about 8 yearsJust to clarify - is this an alternative to the packages mentioned in the question?
-
Alex Kyriakidis about 8 years@retrograde yeah if you pick this solution you don't have to use a package.
-
Efriandika Pratama almost 8 yearsit is not elegant
-
Joel James almost 8 years@EfriandikaPratama why not?
index.php
file is being used on all HTTP requests. So it is an easy and user-friendly way. -
Efriandika Pratama almost 8 yearsIt is not elegant. More elegant if you put that code in middleware.
-
Anthony over 7 years@EfriandikaPratama saying the same thing over and over doesn't prove your point.
-
Ole K over 7 yearsThis is really good solutions, also the OPTIONS method to check if Origin is allowed - like it in the middleware - But for some reason I can not get it all running for POST methods in laravel 5.X - Any ideas?
-
bashleigh about 7 yearsDid you add a method spoof somewhere? When I call POST/GET I get to this middleware but using method OPTIONS I do not get to this middleware on the same route? Really odd... in the route list there is no OPTIONS method so I'm presuming it's possibly that the method OPTIONS is invalid OR being caught elsewhere. This is laravel 5.4 so could be something that's been added?
-
MM2 about 6 yearsit is good if you want to enable CORS for your complete app, but not applicable if you want to enable CORS on certain routes. which I think make more sense to use Middleware instead.
-
arikanmstf almost 6 yearsNote that, for me it is version 5.6 , and I also needed to add
\App\Http\Middleware\Cors::class
at Kernel.php, insideprotected $middleware
array. If anyone has suffer like me, can try this -
shashi verma over 5 years@AlexKyriakidis Thanks for the solution, as I am using the laravel5.7 and I have this syntax
return $next($request);
in my middleware. Should I use this or not? -
ronaldtgi over 5 yearsThis is short and sweet, I think protecting in middleware isn't necessary when all routes are already protected with OAuth or JWT.
-
Chamidu Jayaruwan almost 5 yearsThis will enable access for the whole site / program, not just APIs.
-
darksoulsong almost 5 yearsThis is failing on OPTIONS.
-
darksoulsong almost 5 yearsAwesome, I read your blog post and it worked like a charm. Thanks!
-
Delmontee over 4 years@arikanmstf you just made my week!! This was the problem I was having with my CORS. You are right, adding it to the protected $middleware in kernel.php fixed it! Many thanks.
-
Arun P over 4 years@Rishabh I Was just checking about some CORS related Laravel issues, almost every answer is just the same, but this one is actually very nice ..
-
Ogbonna Vitalis over 4 yearsThank you for this. I am tired of installing bunch of packages just to implement a simple feature
-
Maxim Abdalov over 4 yearsJust add App\Http\Middleware\CORS::class in protected $middleware, and it will work for any request
-
Bahman.A over 4 yearsI have been looking for details on each of the config file's elements especially 'exposedHeaders' and 'supportsCredentials', but unfortunately haven't had any success yet, do you mind to give some details on them or maybe post a reference please? much appreciated!!
-
user931018 over 4 yearsTHANK YOU! Jeez I've struggled with this for weeks. None of the packages worked for me. This is great!
-
Cleanshooter about 4 yearsThis didn't not work for me in Laravel 6.9, this did: github.com/fruitcake/laravel-cors
-
George almost 4 yearsThis solution is incomplete. It solved partially the CORS error, it didn't work on some POST requests.
-
mili almost 4 yearsThis is a nice and simple solution, much thanks. But I changed route on my web.php to get it working on Laravel 5.5
Route::get('example', 'ExampleController@dummy')->middleware(CORS::class);
-
Prashant about 3 yearsWorked like a charm for L5.2 for me.. just a quick note, CORS handling is inbuilt with L8 now.. Thanks
-
Bob Arezina almost 3 yearsThis is a great solution. It's unfortunate that Laravel doesn't have an inbuilt quick way to turn this off.
-
Bob Arezina almost 3 yearsThis solution is generally too complex for those that want their local development environment to just work without the pain of CORS.