Delay backend controller middleware until after request is processed (#4190)

Credit to @bennothommo. Fixes #4183.
This commit is contained in:
Ben Thomson 2019-03-21 15:19:28 +08:00 committed by Luke Towers
parent a2315624df
commit 3363b219f6
2 changed files with 47 additions and 28 deletions

View File

@ -50,11 +50,23 @@ class BackendController extends ControllerBase
*/
protected $cmsHandling = false;
/**
* Stores the requested controller so that the constructor is only run once
*
* @var Backend\Classes\Controller
*/
protected $requestedController;
/**
* Instantiate a new BackendController instance.
*/
public function __construct()
{
$this->middleware(function ($request, $next) {
// Process the request before retrieving controller middleware, to allow for the session and auth data
// to be made available to the controller's constructor.
$response = $next($request);
// Find requested controller to determine if any middleware has been attached
$pathParts = explode('/', str_replace(Request::root() . '/', '', Request::url()));
if (count($pathParts)) {
@ -69,13 +81,20 @@ class BackendController extends ControllerBase
$action = $requestedController['action'];
// Collect applicable middleware and insert middleware into pipeline
collect($requestedController['controller']->getMiddleware())->reject(function ($data) use ($action) {
$controllerMiddleware = collect($requestedController['controller']->getMiddleware())
->reject(function ($data) use ($action) {
return static::methodExcludedByOptions($action, $data['options']);
})->pluck('middleware')->map(function ($middleware) {
$this->middleware($middleware);
})
->pluck('middleware');
foreach ($controllerMiddleware as $middleware) {
$middleware->call($requestedController['controller'], $request, $response);
}
}
}
return $response;
});
}
}
$this->extendableConstruct();
}
@ -224,6 +243,10 @@ class BackendController extends ControllerBase
*/
protected function findController($controller, $action, $inPath)
{
if (isset($this->requestedController)) {
return $this->requestedController;
}
/*
* Workaround: Composer does not support case insensitivity.
*/
@ -236,16 +259,16 @@ class BackendController extends ControllerBase
}
if (!class_exists($controller)) {
return false;
return $this->requestedController = null;
}
$controllerObj = App::make($controller);
if ($controllerObj->actionExists($action)) {
return $controllerObj;
return $this->requestedController = $controllerObj;
}
return false;
return $this->requestedController = null;
}
/**

View File

@ -33,20 +33,16 @@ class Auth extends Controller
{
parent::__construct();
$this->middleware(function ($request, $next) {
$response = $next($request);
$this->middleware(function ($request, $response) {
// Clear Cache and any previous data to fix Invalid security token issue, see github: #3707
$response->headers->set('Cache-Control', 'no-cache, no-store, must-revalidate');
return $response;
})->only('signin');
// Only run on HTTPS connections
if (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] === "on") {
$this->middleware(function ($request, $next) {
$response = $next($request);
$this->middleware(function ($request, $response) {
// Add HTTP Header 'Clear Site Data' to remove all Sensitive Data when signout, see github issue: #3707
$response->headers->set('Clear-Site-Data', 'cache, cookies, storage, executionContexts');
return $response;
})->only('signout');
}