A PSR-15 compatible middleware to prevent CSRF. This middleware checks every POST, PATCH, PUT and DELETE requests for a CSRF token. The token is stored in session request attribute.
- PHP >= 7.1
- A PSR-7 http message implementation and PSR-17 http factory implementation (ex. Embryo-Http)
- A PSR-15 http server request handlers implementation (ex. Embryo-Middleware)
- A PSR-15 session middleware (Ex. Embryo-Session)
- A PSR response emitter (ex. Embryo-Emitter)
Using Composer:
$ composer require davidecesarano/embryo-csrf
Add Embryo\CSRF\CsrfMiddleware
to middleware dispatcher:
use Embryo\Http\Emitter\Emitter;
use Embryo\Http\Server\RequestHandler;
use Embryo\Http\Factory\{ServerRequestFactory, ResponseFactory};
use Embryo\CSRF\CsrfMiddleware;
$request = (new ServerRequestFactory)->createServerRequestFromServer();
$response = (new ResponseFactory)->createResponse();
$session = new Session;
$middleware = new RequestHandler;
$emitter = new Emitter;
// example: generate form input
class GenerateInputMiddleware implements MiddlewareInterface
{
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$response = $handler->handle($request);
$session = $request->getAttribute('session');
$token = $session->get('csrf_token');
return $response->write('<input type="hidden" name="csrf_token" value="'.end($token).'">');
}
}
// SessionMiddleware
$middleware->add(
(new SessionMiddleware)
->setSession($session)
->setOptions([
'use_cookies' => false,
'use_only_cookies' => true
])
);
// CsrfMiddleware
$middleware->add(CsrfMiddleware::class);
// GenerateInputMiddleware
$middleware->add(GenerateInputMiddleware::class);
$response = $middleware->dispatch($request, $response);
$emitter->emit($response);
You may quickly test this using the built-in PHP server going to http://localhost:8000.
$ cd example
$ php -S localhost:8000
Set session request attribute. If it's not provided, use $request->getAttribute('session')
.
Set the form input name. If it's not provided, use csrf_token
.
Set the session key. If it's not provided, use $session->get('csrf_token')
.
Set limit the number of token to store in the session. If it's not provided, is 5
.