Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ee0fb1a

Browse filesBrowse files
committed
adding after filter using kernel.response listener
1 parent 57d9c48 commit ee0fb1a
Copy full SHA for ee0fb1a

File tree

Expand file treeCollapse file tree

1 file changed

+70
-14
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+70
-14
lines changed

‎cookbook/event_dispatcher/before_after_filters.rst

Copy file name to clipboardExpand all lines: cookbook/event_dispatcher/before_after_filters.rst
+70-14Lines changed: 70 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,16 @@ token.
3030
in config and neither database setup nor authentication via
3131
the Security component will be used.
3232

33-
Creating a before filter with a controller.request event
34-
--------------------------------------------------------
33+
Adding a hash to a JSON Response
34+
--------------------------------
35+
36+
In the same context as the token example imagine that we want to add a sha1
37+
hash (with a salt using that token) to all our responses.
38+
39+
So, after generating a JSON response, this hash has to be added to the response.
40+
41+
Before and after filters with kernel.controller / kernel.response events
42+
------------------------------------------------------------------------
3543

3644
Basic Setup
3745
~~~~~~~~~~~
@@ -67,14 +75,18 @@ You can add basic token configuration using ``config.yml`` and the parameters ke
6775
));
6876
6977
Tag Controllers to be checked
70-
-----------------------------
78+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7179

7280
A ``kernel.controller`` listener gets notified on every request, right before
73-
the controller is executed. First, you need some way to identify if the controller
74-
that matches the request needs token validation.
81+
the controller is executed. Same happens to ``kernel.response`` listeners
82+
after the controller returns a Response object.
83+
84+
So, first, you need some way to identify if the controller that matches the
85+
request needs token validation. Regarding the response, you will also need
86+
some way to identify that the response needs to be hashed.
7587

7688
A clean and easy way is to create an empty interface and make the controllers
77-
implement it::
89+
implement it:
7890

7991
namespace Acme\DemoBundle\Controller;
8092

@@ -83,15 +95,33 @@ implement it::
8395
// Nothing here
8496
}
8597

98+
And also create a HashedResponse object extending Response
99+
100+
namespace Acme\DemoBundle\Response;
101+
102+
use Symfony\Component\HttpFoundation\Response;
103+
104+
class HashedResponse extends Response
105+
{
106+
// Nothing here
107+
}
108+
86109
A controller that implements this interface simply looks like this::
87110

111+
use Acme\DemoBundle\Controller\TokenAuthenticatedController;
112+
use Acme\DemoBundle\Response\HashedResponse;
113+
88114
class FooController implements TokenAuthenticatedController
89115
{
90-
// ... Your actions that need authentication
116+
// An action that needs authentication and signature
117+
public function barAction()
118+
{
119+
return new HashedResponse('Hello world');
120+
}
91121
}
92122

93123
Creating an Event Listener
94-
--------------------------
124+
~~~~~~~~~~~~~~~~~~~~~~~~~~
95125

96126
Next, you'll need to create an event listener, which will hold the logic
97127
that you want executed before your controllers. If you're not familiar with
@@ -101,10 +131,12 @@ event listeners, you can learn more about them at :doc:`/cookbook/service_contai
101131
namespace Acme\DemoBundle\EventListener;
102132

103133
use Acme\DemoBundle\Controller\TokenAuthenticatedController;
134+
use Acme\DemoBundle\Response\HashedResponse;
135+
104136
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
105137
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
106138

107-
class BeforeListener
139+
class BeforeAndAfterListener
108140
{
109141
private $tokens;
110142

@@ -132,14 +164,34 @@ event listeners, you can learn more about them at :doc:`/cookbook/service_contai
132164
}
133165
}
134166
}
167+
168+
public function onKernelResponse(FilterResponseEvent $event)
169+
{
170+
$response = $event->getResponse();
171+
172+
if ($response instanceof HashedResponse) {
173+
$token = $event->getRequest()->get('token');
174+
175+
$hash = sha1($response->getContent() . $token);
176+
177+
$response->setContent(
178+
json_encode(array(
179+
'hash' => $hash,
180+
'content' => $response->getContent(),
181+
))
182+
);
183+
}
184+
}
135185
}
136186

137187
Registering the Listener
138-
------------------------
188+
~~~~~~~~~~~~~~~~~~~~~~~~
139189

140190
Finally, register your listener as a service and tag it as an event listener.
141191
By listening on ``kernel.controller``, you're telling Symfony that you want
142-
your listener to be called just before any controller is executed:
192+
your listener to be called just before any controller is executed. And by
193+
listening on ``kernel.response``, your listener will be called after returning
194+
a Response:
143195

144196
.. configuration-block::
145197

@@ -148,25 +200,29 @@ your listener to be called just before any controller is executed:
148200
# app/config/config.yml (or inside your services.yml)
149201
services:
150202
demo.tokens.action_listener:
151-
class: Acme\DemoBundle\EventListener\BeforeListener
203+
class: Acme\DemoBundle\EventListener\BeforeAndAfterListener
152204
arguments: [ %tokens% ]
153205
tags:
154206
- { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
207+
- { name: kernel.event_listener, event: kernel.response, method: onKernelResponse }
155208
156209
.. code-block:: xml
157210
158211
<!-- app/config/config.xml (or inside your services.xml) -->
159-
<service id="demo.tokens.action_listener" class="Acme\DemoBundle\EventListener\BeforeListener">
212+
<service id="demo.tokens.action_listener" class="Acme\DemoBundle\EventListener\BeforeAndAfterListener">
160213
<argument>%tokens%</argument>
161214
<tag name="kernel.event_listener" event="kernel.controller" method="onKernelController" />
215+
<tag name="kernel.event_listener" event="kernel.response" method="onKernelResponse" />
162216
</service>
163217
164218
.. code-block:: php
165219
166220
// app/config/config.php (or inside your services.php)
167221
use Symfony\Component\DependencyInjection\Definition;
168222
169-
$listener = new Definition('Acme\DemoBundle\EventListener\BeforeListener', array('%tokens%'));
223+
$listener = new Definition('Acme\DemoBundle\EventListener\BeforeAndAfterListener', array('%tokens%'));
170224
$listener->addTag('kernel.event_listener', array('event' => 'kernel.controller', 'method' => 'onKernelController'));
225+
$listener->addTag('kernel.event_listener', array('event' => 'kernel.response', 'method' => 'onKernelResponse'));
171226
$container->setDefinition('demo.tokens.action_listener', $listener);
172227
228+

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.