The default Web bundle includes CSRF protection middleware. To install it in alternative bundles:
To activate the extension add Spiral\Bootloader\Http\CsrfBootloader
to list of App bootloaders:
[
//...
Spiral\Bootloader\Http\CsrfBootloader::class,
]
The extension will activate Spiral\Csrf\Middleware\CsrfMiddleware
to issue a unique token for every user.
The extension provides two middleware, which activates the protection on your routes or globally. To protect all the
requests except for GET
, HEAD
, OPTIONS
use Spiral\Csrf\Middleware\CsrfFirewall
:
use Spiral\Csrf\Middleware\CsrfFirewall;
// ...
public function boot(RouterInterface $router): void
{
$route = new Route('/', new Target\Action(HomeController::class, 'index'));
$router->setRoute(
'index',
$route->withMiddleware(CsrfFirewall::class)
);
}
Note
To protect against all the HTTP verbs useSpiral\Csrf\Middleware\StrictCsrfFirewall
.
Once the protection is activated, you must sign every request with the token available via PSR-7 attribute csrfToken
.
To receive this token in the controller or view:
public function index(ServerRequestInterface $request): void
{
$csrfToken = $request->getAttribute('csrfToken');
}
Every POST
/PUT
/DELETE
request from the user must include this token as POST parameter csrf-token
or
header X-CSRF-Token
. Users will receive 412 Bad CSRF Token
if a token is missing or not set.
use Psr\Http\Message\ServerRequestInterface;
// ...
public function index(ServerRequestInterface $request): string
{
$form = '
<form method="post">
<input type="hidden" name="csrf-token" value="{csrfToken}"/>
<input type="text" name="value"/>
<input type="submit"/>
</form>
';
$form = \str_replace(
'{csrfToken}',
$request->getAttribute('csrfToken'),
$form
);
return $form;
}
To activate CSRF protection globally register Spiral\Csrf\Middleware\CsrfFirewall
or Spiral\Csrf\Middleware\StrictCsrfFirewall
via Spiral\Bootloader\Http\HttpBootloader
:
use Spiral\Csrf\Middleware\CsrfFirewall;
use Spiral\Bootloader\Http\HttpBootloader;
// ...
public function boot(HttpBootloader $http): void
{
$http->addMiddleware(CsrfFirewall::class);
}