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
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).
When a page is loaded there aren't any cookies set in browser. I need csrf when a user logs in.
Within the form tag I set the token value with
#csrf.
I don't remember changing anything in Kernel.php but here it is:
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,
\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',
'bindings',
],
];
/**
* 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,
];
/**
* The priority-sorted list of middleware.
*
* This forces non-global middleware to always be in the given order.
*
* #var array
*/
protected $middlewarePriority = [
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\Authenticate::class,
\Illuminate\Routing\Middleware\ThrottleRequests::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Auth\Middleware\Authorize::class,
];
}
by default there should be an XSRF-TOKEN, and session cookie set by the framework right? What am I missing?
Laravel v6.4.0
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 used middlewares for many Laravel applications, but this is a stupid situation never happened to me before. The middleware always returns false for Auth::check()
This is routes of User module
<?php
Route::group(['middleware' => 'web', 'namespace' => 'Modules\User\Http\Controllers'], function () {
Route::get('/', 'UserController#index');
Route::get('login', 'LoginController#showLoginForm')->name('login');
Route::post('login', 'LoginController#login');
Route::post('logout', 'LoginController#logout')->name('logout');
});
Route::group(['middleware' => 'admin', 'prefix' => 'user', 'namespace' => 'Modules\User\Http\Controllers'], function () {
Route::get('register', 'RegisterController#showRegistrationForm')->name('register');
Route::post('register', 'RegisterController#register');
});
This is AdminMiddleware inside the User module
<?php
namespace Modules\User\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class AdminMiddleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle(Request $request, Closure $next)
{
$log = Auth::check();
dd($log);
return $next($request);
}
}
and this is 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,
'admin' => \Modules\User\Http\Middleware\AdminMiddleware::class
];
But the result of dd($log) is always false. What is wrong here?!!!
You also need to add web middleware to User module routes group.
Because the session starts there.
Just saying, another solution is that you added it to the global middleware stack instead of the web middleware group! (Only add it to web, it can't be both)
please append your middleware address:
\Modules\User\Http\Middleware\AdminMiddleware::class
to
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,
\Modules\User\Http\Middleware\AdminMiddleware::class //this is your middleware.
],
'api' => [
'throttle:60,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
you can set your middleware's priority to be loaded after StartSession to be sure it will be loaded after the session starts.
in kernel.php
protected $middlewarePriority = [
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\Modules\User\Http\Middleware\AdminMiddleware::class
\App\Http\Middleware\Authenticate::class,
\Illuminate\Routing\Middleware\ThrottleRequests::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Auth\Middleware\Authorize::class,
\App\Http\Middleware\CheckProfileRequiredData::class, // putting CheckProfileRequiredData after Auth priority is required! to perform it's check after auth middleware
\App\Http\Middleware\CheckUserMustPayWithoutAnsweringDietRequiredQuestions::class,
];
Part of my application does not utilize standard user authentication, and lies outside the auth group in my routes file. I am using Laravel Passport, VueJS2, VueRouter. Laravel is serving two blade files; one for the authenticated part of the application, and the other for the non-authenticated part.
However, I find that when trying to access that part of the application, it still requires me to be authenticated (I get the 401: Unauthorized error).
I have looked through my configuration files, and I can't seem to figure out why this would be displayed.
My api.php file:
<?php
use Illuminate\Http\Request;
Route::group(['middleware' => 'auth'], function () {
// A lot of routes here...
});
// These should not be guarded
// This is the route that triggers the unauthenticated message
Route::post('authenticate', 'TestController#authenticate');
THe JS file that makes the request:
authenticateUser: function() {
var data = {
'id' : this.$route.params.id,
'passcode' : this.state.password,
};
var that = this;
axios({
method: 'post',
url: '/api/authenticate',
withCredentials: true,
data: data,
}).then(function(response) {
swal('Great!', 'You have been authenticated.', 'success');
that.$router.push('/client/create/' + that.$route.params.id);
}, function(error) {
swal('Woah!', 'Wrong password, go away.', 'error');
});
}
Here is my kernel.php file:
<?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 = [
\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\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array
*/
protected $routeMiddleware = [
'test.auth' => \App\Http\Middleware\VerifyTestAccess::class,
'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,
'test.state' => \App\Http\Middleware\VerifyTestState::class,
];
}