Add XSRF to backend, simplify CMS controller run() method
runInternal has been removed because we do not want to blanket our response logic over every single response, only the happy path. This is because it is impossible to remove. So it is better to take the inverted approach, where if you want the CMS' headers in your custom response, add them yourself. This becomes easy via the new makeResponse() method
This commit is contained in:
parent
9d120ad66b
commit
63f65a3f25
|
|
@ -174,6 +174,13 @@ class Controller extends Extendable
|
|||
return Response::make(Lang::get('system::lang.page.invalid_token.label'), 403);
|
||||
}
|
||||
|
||||
if (
|
||||
Config::get('cms.enableCsrfProtection', true) &&
|
||||
Config::get('cms.enableXsrfCookies', true)
|
||||
) {
|
||||
$this->setResponseCookie($this->makeXsrfCookie());
|
||||
}
|
||||
|
||||
/*
|
||||
* Check forced HTTPS protocol.
|
||||
* @see \System\Traits\SecurityController
|
||||
|
|
|
|||
|
|
@ -138,27 +138,6 @@ class Controller
|
|||
* @return BaseResponse Returns the response to the provided URL
|
||||
*/
|
||||
public function run($url = '/')
|
||||
{
|
||||
$response = $this->runInternal($url);
|
||||
|
||||
if (
|
||||
Config::get('cms.enableCsrfProtection', true) &&
|
||||
Config::get('cms.enableXsrfCookies', true) &&
|
||||
$response instanceof BaseResponse
|
||||
) {
|
||||
$this->addXsrfCookie($response);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the request internally
|
||||
*
|
||||
* @param string $url Specifies the requested page URL.
|
||||
* @return BaseResponse Returns the response to the provided URL
|
||||
*/
|
||||
protected function runInternal($url = '/')
|
||||
{
|
||||
if ($url === null) {
|
||||
$url = Request::path();
|
||||
|
|
@ -176,6 +155,13 @@ class Controller
|
|||
return Response::make(Lang::get('system::lang.page.invalid_token.label'), 403);
|
||||
}
|
||||
|
||||
if (
|
||||
Config::get('cms.enableCsrfProtection', true) &&
|
||||
Config::get('cms.enableXsrfCookies', true)
|
||||
) {
|
||||
$this->setResponseCookie($this->makeXsrfCookie());
|
||||
}
|
||||
|
||||
/*
|
||||
* Hidden page
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?php namespace System\Traits;
|
||||
|
||||
use Response;
|
||||
use Symfony\Component\HttpFoundation\HeaderBag;
|
||||
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
|
||||
use Symfony\Component\HttpFoundation\Response as BaseResponse;
|
||||
|
||||
/**
|
||||
|
|
@ -24,7 +24,7 @@ trait ResponseMaker
|
|||
protected $responseOverride = null;
|
||||
|
||||
/**
|
||||
* @var Symfony\Component\HttpFoundation\HeaderBag
|
||||
* @var Symfony\Component\HttpFoundation\ResponseHeaderBag
|
||||
*/
|
||||
protected $responseHeaderBag = null;
|
||||
|
||||
|
|
@ -36,6 +36,7 @@ trait ResponseMaker
|
|||
public function setStatusCode($code)
|
||||
{
|
||||
$this->statusCode = (int) $code;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
|
@ -57,6 +58,7 @@ trait ResponseMaker
|
|||
public function setResponse($response)
|
||||
{
|
||||
$this->responseOverride = $response;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
|
@ -71,7 +73,7 @@ trait ResponseMaker
|
|||
public function setResponseHeader($key, $values, $replace = true)
|
||||
{
|
||||
if ($this->responseHeaderBag === null) {
|
||||
$this->responseHeaderBag = new HeaderBag;
|
||||
$this->responseHeaderBag = new ResponseHeaderBag;
|
||||
}
|
||||
|
||||
$this->responseHeaderBag->set($key, $values, $replace);
|
||||
|
|
@ -88,7 +90,7 @@ trait ResponseMaker
|
|||
public function setResponseCookie($cookie)
|
||||
{
|
||||
if ($this->responseHeaderBag === null) {
|
||||
$this->responseHeaderBag = new HeaderBag;
|
||||
$this->responseHeaderBag = new ResponseHeaderBag;
|
||||
}
|
||||
|
||||
if (is_string($cookie) && function_exists('cookie')) {
|
||||
|
|
@ -100,6 +102,15 @@ trait ResponseMaker
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the header response bag
|
||||
* @return Symfony\Component\HttpFoundation\ResponseHeaderBag|null
|
||||
*/
|
||||
public function getResponseHeaders()
|
||||
{
|
||||
return $this->responseHeaderBag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares a response that considers overrides and custom responses.
|
||||
* @param mixed $contents
|
||||
|
|
@ -112,11 +123,12 @@ trait ResponseMaker
|
|||
}
|
||||
|
||||
if (is_string($contents)) {
|
||||
$contents = Response::make($contents, $this->statusCode);
|
||||
$contents = Response::make($contents, $this->getStatusCode());
|
||||
}
|
||||
|
||||
if ($contents instanceof BaseResponse && $this->responseHeaderBag !== null) {
|
||||
$contents = $contents->withHeaders($this->responseHeaderBag);
|
||||
$responseHeaders = $this->getResponseHeaders();
|
||||
if ($responseHeaders && $contents instanceof BaseResponse) {
|
||||
$contents = $contents->withHeaders($responseHeaders);
|
||||
}
|
||||
|
||||
return $contents;
|
||||
|
|
|
|||
|
|
@ -21,28 +21,23 @@ trait SecurityController
|
|||
* Adds anti-CSRF cookie.
|
||||
* Adds a cookie with a token for CSRF checks to the response.
|
||||
*
|
||||
* @param BaseResponse $response The response object to add the cookie to
|
||||
* @return BaseResponse
|
||||
* @return \Symfony\Component\HttpFoundation\Cookie
|
||||
*/
|
||||
protected function addXsrfCookie(BaseResponse $response)
|
||||
protected function makeXsrfCookie()
|
||||
{
|
||||
$config = Config::get('session');
|
||||
|
||||
$response->headers->setCookie(
|
||||
new Cookie(
|
||||
'XSRF-TOKEN',
|
||||
Session::token(),
|
||||
Carbon::now()->addMinutes((int) $config['lifetime'])->getTimestamp(),
|
||||
$config['path'],
|
||||
$config['domain'],
|
||||
$config['secure'],
|
||||
false,
|
||||
false,
|
||||
$config['same_site'] ?? null
|
||||
)
|
||||
return new Cookie(
|
||||
'XSRF-TOKEN',
|
||||
Session::token(),
|
||||
Carbon::now()->addMinutes((int) $config['lifetime'])->getTimestamp(),
|
||||
$config['path'],
|
||||
$config['domain'],
|
||||
$config['secure'],
|
||||
false,
|
||||
false,
|
||||
$config['same_site'] ?? null
|
||||
);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in New Issue