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.
This question is related to
cors
laravel-5.3
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.
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
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
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
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: *');
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');
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. ☑
Just add this to your view:
<?php header("Access-Control-Allow-Origin: *"); ?>
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 in app/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';
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,
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");
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,
];
Just add this to your code Controller
return response()->json(compact('token'))->header("Access-Control-Allow-Origin", "*");
Source: Stackoverflow.com