Adding Access-Control-Allow-Origin header response in Laravel 5.3 Passport
CorsLaravel 5.3Cors Problem Overview
I'm new to Laravel and am doing some Laravel 5.3 Passport project with OAuth2.0 password grant. When I curl the API with the params it responds with token. However, in browser it needs an additional security that the endpoint should add because my request is coming from localhost while the API is located in my VM. Here's the error:
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. The response had HTTP status code 400.
I know what the issue is but I don't know where to put to include that header since this is a third party app.
Thank you in advance experts. Please help.
Cors Solutions
Solution 1 - Cors
The simple answer is to set the Access-Control-Allow-Origin
header to localhost
or *
. Here's how I usually do it:
Create a simple middleware called Cors
:
php artisan make:middleware Cors
Add the following code to app/Http/Middleware/Cors.php
:
public function handle($request, Closure $next)
{
return $next($request)
->header('Access-Control-Allow-Origin', '*')
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
}
You can replace the *
with localhost
or keep it as it is.
Next step is to load the middleware. Add the following line to the $routeMiddleware
array in app/Http/Kernel.php
.
'cors' => \App\Http\Middleware\Cors::class,
And the final step is to use the middleware on the routes to which you want to set the access origin headers. Assuming you are talking about the new api routes in laravel 5.3, the place to do it is app/Providers/RouteServiceProvider.php
, inside the mapApiRoutes()
function (you can remove or comment the previous code of the function):
Route::group([
'middleware' => ['api', 'cors'],
'namespace' => $this->namespace,
'prefix' => 'api',
], function ($router) {
//Add you routes here, for example:
Route::apiResource('/posts','PostController');
});
Solution 2 - Cors
The simple answer is to set the Access-Control-Allow-Origin header to localhost or *. Here's how I usually do it:
Add the following code to bootstrap/app.php:
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: *');
header('Access-Control-Allow-Headers: *');
WARNING: Only do this in your developer environment.
Solution 3 - Cors
You could also use the great laravel-cors package by barryvdh.
After you have the package installed, the easiest way to get CORS support for all your routes is to add the middleware like this in Http/Kernel.php:
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Barryvdh\Cors\HandleCors::class,
];
If you dont want to have CORS support on all your routes you should make a new OPTIONS route for /oauth/token
and add the cors middleware to that route only.
Edit for Laravel 8
Laravel 8 already has CORS Support built in - HandleCors
middleware is defined in your global middleware stack by default and can be configured in your application's config/cors.php
config file.
If you update your Laravel application be sure to change out barryvdh's package with the supplied middleware: \Fruitcake\Cors\HandleCors::class
Solution 4 - Cors
For those who didn't solve the problem setting route middleware in App\Http\Kernel
, try to set global middleware. In App\Http\Middleware\Cors
:
public function handle($request, Closure $next)
{
return $next($request)->header('Access-Control-Allow-Origin', '*')
->header('Access-Control-Allow-Methods','GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS')
->header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
}
In App\Http\Kernel
:
protected $middleware = [
...
\App\Http\Middleware\Cors::class,
];
Solution 5 - Cors
Create A Cors.php File in App/Http/Middleware and paste this in it. ☑
<?php
namespace App\Http\Middleware;
use Closure;
class Cors { 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, Authorization',
];
if ($request->getMethod() == "OPTIONS"){
//The client-side application can set only headers allowed in Access-Control-Allow-Headers
return response()->json('OK',200,$headers);
}
$response = $next($request);
foreach ($headers as $key => $value) {
$response->header($key, $value);
}
return $response;
} }
And Add This Line In Your Kernel.php after the "Trust Proxies::Class" Line.
\App\Http\Middleware\Cors::class,
Thats It You have Allowed All Cors Header. ☑
Solution 6 - Cors
After
https://github.com/fruitcake/laravel-cors
I had to change in cors.php file as below
* Sets the Access-Control-Allow-Credentials header.
*/
'supports_credentials' => true,
Solution 7 - Cors
Be careful, you can not modify the preflight. In addition, the browser (at least chrome) removes the "authorization" header ... this results in some problems that may arise according to the route design. For example, a preflight will never enter the passport route sheet since it does not have the header with the token.
In case you are designing a file with an implementation of the options method, you must define in the route file web.php one (or more than one) "trap" route so that the preflght (without header authorization) can resolve the request and Obtain the corresponding CORS headers. Because they can not return in a middleware 200 by default, they must add the headers on the original request.
Solution 8 - Cors
If you've applied the CORS middleware and it's still not working, try this.
If the route for your API is:
Route::post("foo", "MyController"})->middleware("cors");
Then you need to change it to allow for the OPTIONS method:
Route::match(['post', 'options'], "foo", "MyController")->middleware("cors");
Solution 9 - Cors
If for some reason it's still not working. First option for Laravel The second option for any application
FIRST OPTION:
-
As in the example above, we create middleware
php artisan make:middleware Cors
-
Add the following code to
app/Http/Middleware/Cors.php
:public function handle($request, Closure $next) { return $next($request) ->header('Access-Control-Allow-Origin', '*') ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS') ->header('Access-Control-Allow-Headers', 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'); }
Look closely, the amount of data in the header ->header('Access-Control-Allow-Headers',
-
Step three, add middleware to
$routeMiddleware
array inapp/Http/Kernel.php
protected $routeMiddleware = [ .... 'cors' => \App\Http\Middleware\Cors::class, ];
SECOND OPTION:
-
Open the nginx.conf settings for your domain.
sudo nano /etc/nginx/sites-enabled/your-domain.conf
-
Inside the server settings server
{ listen 80; .... }
please add the following code:add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH';
Solution 10 - Cors
Just add this to your code Controller
return response()->json(compact('token'))->header("Access-Control-Allow-Origin", "*");
Solution 11 - Cors
Few steps to add Access-Control-Allow-Origin
header to localhost or *.
Step 1: Create Cors middleware :
php artisan make:middleware Cors
Step 2: Set header in Cors middleware like this
public function handle($request, Closure $next)
{
$response = $next($request);
$response->headers->set('Access-Control-Allow-Origin' , '*');
$response->headers->set('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT, DELETE');
$response->headers->set('Access-Control-Allow-Headers', 'Content-Type, Accept, Authorization, X-Requested-With, Application');
return $response;
}
Step 3: We need to add Cors class in app/Http/Kernel.php
protected $middleware = [
....
\App\Http\Middleware\Cors::class,
];
Here no needed to check any middleware
because we add Cors class in $middleware
in app/Http/Kernel.php
Solution 12 - Cors
Working Solution
Step 1: Create Cors middleware
php artisan make:middleware Cors
Step 2: Set header in Cors middleware inside handle function
return $next($request)
->header('Access-Control-Allow-Origin', '*')
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
Step 3: Add Cors class in app/Http/Kernel.php
protected $routeMiddleware = [
....
'cors' => \App\Http\Middleware\Cors::class,
];
Step 4: Replace mapApiRoutes in app/providers/routeServiceProvider.php
Route::prefix('api')
->middleware(['api', 'cors'])
->namespace($this->namespace)
->group(base_path('routes/api.php'));
Step 5: Add your routes in routes/api.php
Route::post('example', 'controllerName@functionName')->name('example');
Solution 13 - Cors
Just add this to your view:
<?php header("Access-Control-Allow-Origin: *"); ?>
Solution 14 - Cors
I am using Laravel 8 and just installed the fruitcake/laravel-cors
and use it in app/Http/Kernel.php
like blow:
protected $middleware = [
....
\Fruitcake\Cors\HandleCors::class,
];
note : add it to end of array like me
Solution 15 - Cors
You can do it easily by adding headers in bootstrap/app.php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: *');
header('Access-Control-Allow-Headers: *');
Solution 16 - Cors
You don't need do anything extra. Laravel already have inbuilt provision - read from here https://stackoverflow.com/a/70361284/2612926