With the Middleware correctly loaded for the route, it’s time to add the required code in the route’s handler.
The handler that you put it in is up to your discretion.
For this article, let’s assume that it is in the default handler that comes with applications generated with the Mezzio Skeleton, src/App/Handler/HomePageHandler.php
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| public function handle(ServerRequestInterface $request)
: ResponseInterface
{
$data = [];
$form = (new \Laminas\Form\Annotation\AnnotationBuilder())
->createForm(\App\Entity\PreviewBookDownload::class);
/** @var \Mezzio\Csrf\CsrfGuardInterface $guard */
$guard = $request->getAttribute(
\Mezzio\Csrf\CsrfMiddleware::GUARD_ATTRIBUTE
);
if ($request->getMethod() === 'GET') {
$data['__csrf'] = $guard->generateToken();
}
if ($request->getMethod() === 'POST') {
$data = $request->getParsedBody();
$form->setData($data);
$token = $data['__csrf'] ?? '';
if ($guard->validateToken($token) && $form->isValid()) {
// Handle a positive form submission
// ...
}
}
return new HtmlResponse(
$this->template->render(
'app::home-page', $data
)
);
}
|
That it instantiates the form object in this way isn’t important.
It’s just the approach that I took in this scenario, as I like the functionality which Laminas Form provides for handling request filtering and validation.
Tip
|
If you want to use this approach, you’ll need to run the following command:
1
2
3
| composer require \
laminas/laminas-form \
doctrine/common
|
|
It then retrieves the CSRF guard, by retrieving the CsrfMiddleware::GUARD_ATTRIBUTE
attribute from the request, put there by CsrfMiddleware
, and uses it to initialise a new variable, aptly named $guard
.
It then checks if the HTTP request method was GET
.
If so, it calls $guard’s `generateToken
method to generate a new CSRF token and initialises the __csrf
element of the $data
array with it.
If the request method was POST
, it retrieves the body of the request, containing the form data, by calling $request’s `getParsedBody()
, and stores the retrieved array in $data
.
After doing that, it then passes $data
to a call to $form’s `setData
method, setting the value of the form’s fields with the values supplied in the request body.
After that, it attempts to retrieve the token from $data’s `__csrf
element, and initialise a new variable, named $token
with it.
If the element is not set or is empty, then $token
is set to an empty string.
Following that, it attempts to validate the token, by calling $guard’s `validateToken
method.
It also runs the form’s validation rules on the remainder of the form’s data.
If both method calls succeed, then the remaining code is executed.
If either fails, then the form is displayed again along with an appropriate error message.
I’ve not displayed this specific code, as it’s not essential to the understanding of integrating CSRF tokens into a Mezzio application.
After that, there’s one final aspect of code to cover, which is the returned HtmlResponse object.
This renders the page’s template, after rendering the contents of $data
into it.
If it’s a GET request, then an empty form, containing the CSRF token will be displayed on the page.
If it’s a POST request, then the form will be rendered, with the CSRF token and any applicable error messages.
Join the discussion
comments powered by Disqus