I was creating my first project between Vue 2 and Laravel 6, I could read information from the API through GET, but I was trying to send a CSV file from the frontend http://localhost/8080 to the backend http://127.0.0.1:8000, but I get the following message
Here I get a cors error, which I have reported and I have seen that it is because they are from different servers
My request from Vue is the following:
axios
.post("http://127.0.0.1:8000/api/import", this.file, {
headers: {
"Content-Type": "multipart/form-data",
},
})
.then(function (response) {
console.log(response);
console.log("SUCCESS!!");
})
.catch(function (error) {
console.log(error);
});
The route of my Laravel has the following line
Route::group(['middleware' => 'cors'], function () {
Route::apiResource("naves", "StarwarsController");
Route::post('import', 'StarwarsController#import');});
In the controller I have the following code
public function import(Request $request)
{
return var_dump($request);
$request->file('images');}
And about CORS I have the following information
Cors.php
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)
->header('Access-Control-Allow-Origin', '*')
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS')
->header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
}
}
and Kernel.php
protected $middleware = [
\App\Http\Middleware\TrustProxies::class,
\App\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\Cors::class
];
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'cors' => \App\Http\Middleware\Cors::class,
];
If you could help me I would appreciate it a lot!
Solution:
$origin = (isset($_SERVER['HTTP_ORIGIN'])) ? $_SERVER['HTTP_ORIGIN'] : '*';
header('Access-Control-Allow-Origin: ' . $origin);
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Max-Age: 1000');
header('Access-Control-Allow-Credentials: true');
header('Content-Type: text/html; charset=UTF-8');
if ($this->input->server('REQUEST_METHOD') == 'OPTIONS') {
header('Access-Control-Allow-Headers: authorization, content-type');
echo json_encode(array());
exit;
}
Related
I have hosted laravel and angular application on server it was working before but now it is throwing below error :
Access to XMLHttpRequest at 'https://......login' from origin
'https://.....r.in' has been blocked by CORS policy: Response to
preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource.
I have created CORS middleware :
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class CORS
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle(Request $request, Closure $next)
{
header('Acess-Control-Allow-Origin: *');
header('Acess-Control-Allow-Origin: Content-type, X-Auth-Token, Authorization, Origin');
return $next($request);
}
}
api route file:
Route::group(['middleware' => 'api','cors','prefix' => 'auth'], function ($router) {
Route::post('/login', [AuthController::class, 'login']);
Route::post('/register', [AuthController::class, 'register']);
Route::post('/logout', [AuthController::class, 'logout']);
Route::get('/user-profile', [AuthController::class, 'userProfile']);
});
Kernel.php
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* #var array
*/
protected $middleware = [
// \App\Http\Middleware\TrustHosts::class,
\App\Http\Middleware\TrustProxies::class,
\Fruitcake\Cors\HandleCors::class,
\App\Http\Middleware\PreventRequestsDuringMaintenance::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\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'guest' => \App\Http\Middleware\CORS::class,
];
}
Any solution is highly appreciated, Thanks
the error is in the browser, so you need to have those headers on the response. For this, you need to have middleware for the response, see https://laravel.com/docs/8.x/middleware#middleware-and-responses
$response = $next($request);
// add headers to response here
return $response;
Additional info:
You need to edit your CORS middleware.
it will look like this:
$response = $next($request);
if ($request->getMethod() !== 'OPTIONS') {
return $response;
}
$response->header('Access-Control-Allow-Origin', '*')
->header('Access-Control-Allow-Headers', 'Content-type, X-Auth-Token, Authorization, Origin');
return $response;
You made a few typos:
Acess should be Access
and in the Kernel.php you have
'guest' => \App\Http\Middleware\CORS::class,
But I think it should be
'cors' => \App\Http\Middleware\CORS::class,
because you use cors name in your routes.
Updated again:
The second header should be Access-Control-Allow-Headers instead of Access-Control-Allow-Origin
It might throw another error about allowed methods(because it said preflight request) so you will need to fix it by adding Access-Control-Allow-Methodssee https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS
Regarding the error:
getting Access to XMLHttpRequest at 'https://beta-XXX/api/auth/login' from origin 'https://XXXXX.in' has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response
It says that the preflight request (in that case, it is OPTIONS, not GET or POST) doesn't allow Content-Type. This is because it is not applied to this kind of method. In that case, there should be a new route under middleware cors like
Route::options('/login', ...);
But since you will need it in other places as well, then it is better to customize the CORS middleware for preflight requests through the entire application by adding your Cors middleware into the $middleware array (then it will run for every request). Please try/test that if needed. Then it might be that it is needed only for OPTIONS requests, if it is true then I'd add(I've modified it in the above snippet as well)
if ($request->getMethod() !== 'OPTIONS') {
return $response;
}
WARNING/NOTICE:
if you make it to work, the next step would be to make sure that you specify what origins are allowed in production. Instead of *, you should have a list of domains that are allowed to use it (or even better you can respond with * only for allowed hosts).
I have installed Laravel 7.0 and working with angular 12 as a frontend. I used this package
https://github.com/fruitcake/laravel-cors
This is my kernel.php
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* #var array
*/
protected $middleware = [
\App\Http\Middleware\TrustProxies::class,
\Fruitcake\Cors\HandleCors::class,
\App\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\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
}
cors.php
<?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.
|
| To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
|
*/
'paths' => ['api/*'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => ['*'],
'max_age' => 0,
'supports_credentials' => true,
];
api.php
Route::group(['middleware' => ['api']], function ($router) {
Route::post('/contact-us', [SiteController::class, 'contactUs']);
});
Route::group([
'middleware' => ['api'],
'prefix' => 'auth'
], function ($router) {
Route::post('/login', [AuthController::class, 'login']);
Route::get('/user-profile', [AuthController::class, 'Profile']);
});
I'm getting this error :
Access to XMLHttpRequest at 'http://127.0.0.1:8000/api/auth/login'
from origin 'http://localhost:4200' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested
resource.
Testing with own CORS middleware
No 'Access-Control-Allow-Origin' header is present on the requested resource.
The website handling the request (here localhost:4200) must set this header to allow requests cross-origin. So the package doesn't do anything, apparently.
I cannot help with the package used, but here is how to set the headers with your own middleware (may help others). Change the headers as you see fit. We'll use this for testing:
app/Http/Middleware/Cors.php
<?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)
{
return $next($request)
->header('Access-Control-Allow-Origin', '*')
->header('Access-Control-Allow-Headers', 'Authorization')
->header('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, PATCH');
}
}
In app/Http/Kernel.php we add it to $middleware:
protected $middleware = [
// ...
\App\Http\Middleware\Cors::class,
];
The server should now set the respective headers.
This might not be your solution, but you can at least debug what is different.
Documentation for Access-Control-Allow-...:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers
I'm trying to send a post request from my frontend ( Ionic ) to my backend Laravel ! it return that Cors error. I've already made the Cors class in Laravel and added it the routeMiddleware, I have also tried the solution made by barryvdh and it's also not working. when I try the request using the get method it works but it's not the same case while using post method.
here my handle method in Cors class in laravel :
public function handle($request, Closure $next)
{
header("Access-Control-Allow-Origin: *");
// ALLOW OPTIONS METHOD
$headers = [
'Access-Control-Allow-Origin'=> '*',
'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;
}
middleware array in Kernel.php
protected $middleware = [
\App\Http\Middleware\TrustProxies::class,
\App\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\Cors::class,
];
api part of the middlewareGroups array in Kernel.php
'api' => [
'throttle:60,1',
'bindings',
\App\Http\Middleware\Cors::class,
]
routeMiddleware array in Kernel.php
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'jwt.auth' => Tymon\JWTAuth\Http\Middleware\Authenticate::class,
'jwt.refresh' => Tymon\JWTAuth\Http\Middleware\RefreshToken::class,
'cors' => \App\Http\Middleware\Cors::class,
];
The route I'm trying to call
Route::post('auth/login', 'ApiController#login');
Here the code I'm executing in ionic
login(emaill: string, passwordd: string) {
return this.http.post<any>(
`${environment.laravelBackend}/auth/login`,
{ email: emaill, password: passwordd}
);
}
Anyone knows how I can make this work ?
Thanks in advance
there may be 2 solutions try both if first or second does not work.
1) Sometime, it not works due to the developer's composer version where the API is made, and the machine where you have setup the environment's composer version is different. check it. and if possible, send your and the machine where api is developed's composer version.
2) Add CORS in .htaccess File like this
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods "GET,POST,PUT,DELETE,OPTIONS"
Header set Access-Control-Allow-Credentials "true"
I was wondering if there is a way to restrict access to routes-blades at certain hours or minutes within a day ?
Any documentation about this topic ?
Create a middleware
php artisan make:middleware TimeBasedRestriction
Return a different response or redirect if time isn't appropriate
<?php
namespace App\Http\Middleware;
use Closure;
class TimeBasedRestriction
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
// if not working hours, access forbidden
if (!now()->isBetween('09:00:00', '16:00:00')) {
return response()->json([
'message' => 'Day is over, come back tomorrow'
], 403); // Status forbidden
}
return $next($request);
}
}
Add the middleware to your route middleware in app\Http\Kernel.php
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'restrictedToDayLight' => \App\Http\Middleware\TimeBasedRestriction::class,
];
And add it to your restricted routes in web.php for example
Route::get('/', function () {
return view('welcome');
})->middleware('restrictedToDayLight');
I have added a CORS middleware and it works fine for single routes :-
Route::get('example', ['middleware' => 'cors', function(){
return Response::json(array('name' => 'Steve Jobs', 'company' => 'Apple'));
}]);
But when I apply it to group of routes, it gives error in console :-
(index):1 XMLHttpRequest cannot load http://jotdot.mysite.com/api/authenticate.
Response to preflight request doesn't pass access control
check: No 'Access-Control-Allow-Origin' header is present on
the requested resource. Origin 'http://jotdotfrontend.mysite.com' is
therefore not allowed access.
My group of routes :-
Route::group(['middleware' => 'cors'], function () {
Route::group(['prefix' => 'api'], function()
{
Route::resource('authenticate', 'AuthenticateController', ['only' => ['index']]);
Route::post('authenticate', 'AuthenticateController#authenticate');
});
});
Cors.php
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;
return $next($request);
}
}
I am following https://scotch.io/tutorials/token-based-authentication-for-angularjs-and-laravel-apps and trying to set up backend and frontend on different domains.
Thanks
The problem is that route-based middleware were never applied on OPTIONS request for autogenerated resource-based routes ('cause Route::resource(...) doesn't generate routes for options method?).
So, put yours cors middleware inside global middleware group in app/Http/Kernel.php, just before VerifyCsrfToken middleware:
/**
* The application's global HTTP middleware stack.
*
* #var array
*/
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Ankh\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\CORS::class, // here it is
\App\Http\Middleware\VerifyCsrfToken::class,
];
And entirely remove it from routes.php, like:
// Route::group(['middleware' => 'cors'], function () {
Route::group(['prefix' => 'api'], function() {
Route::resource('authenticate', 'AuthenticateController', ['only' => ['index']]);
Route::post('authenticate', 'AuthenticateController#authenticate');
});
//});
You can try this:
Route::group(['prefix' => 'api', 'middleware' => 'cors'], function()
{
Route::resource('authenticate', 'AuthenticateController', ['only' => ['index']]);
Route::post('authenticate', 'AuthenticateController#authenticate');
});
Try like this,
Route::group([ 'prefix' => 'api', 'middleware' => 'App\Http\Middleware\CORS'], function() {
Route::resource('authenticate', 'AuthenticateController', ['only' => ['index']]);
Route::post('authenticate', 'AuthenticateController#authenticate');
});
Your origin header isn't in your headers array. Instead of setting your origin header using header(), try adding it with your other access control headers like this:
// ALLOW OPTIONS METHOD
$headers = [
'Access-Control-Allow-Origin'=> '*',
'Access-Control-Allow-Methods'=> 'POST, GET, OPTIONS, PUT, DELETE',
'Access-Control-Allow-Headers'=> 'Content-Type, X-Auth-Token, Origin'
];