@@ -30,8 +30,16 @@ token.
30
30
in config and neither database setup nor authentication via
31
31
the Security component will be used.
32
32
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
+ --------------------------------------------------------------------------------
35
43
36
44
Basic Setup
37
45
~~~~~~~~~~~
@@ -67,11 +75,15 @@ You can add basic token configuration using ``config.yml`` and the parameters ke
67
75
));
68
76
69
77
Tag Controllers to be checked
70
- -----------------------------
78
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
71
79
72
80
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.
75
87
76
88
A clean and easy way is to create an empty interface and make the controllers
77
89
implement it::
@@ -80,18 +92,36 @@ implement it::
80
92
81
93
interface TokenAuthenticatedController
82
94
{
83
- // Nothing here
95
+ // ...
96
+ }
97
+
98
+ And also create a ``HashedResponse `` object extending ``Response ``
99
+
100
+ namespace Acme\D emoBundle\R esponse;
101
+
102
+ use Symfony\C omponent\H ttpFoundation\R esponse;
103
+
104
+ class HashedResponse extends Response
105
+ {
106
+ // ...
84
107
}
85
108
86
109
A controller that implements this interface simply looks like this::
87
110
111
+ use Acme\DemoBundle\Controller\TokenAuthenticatedController;
112
+ use Acme\DemoBundle\Response\HashedResponse;
113
+
88
114
class FooController implements TokenAuthenticatedController
89
115
{
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
+ }
91
121
}
92
122
93
123
Creating an Event Listener
94
- --------------------------
124
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
95
125
96
126
Next, you'll need to create an event listener, which will hold the logic
97
127
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
101
131
namespace Acme\DemoBundle\EventListener;
102
132
103
133
use Acme\DemoBundle\Controller\TokenAuthenticatedController;
134
+ use Acme\DemoBundle\Response\HashedResponse;
135
+
104
136
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
105
137
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
106
138
107
- class BeforeListener
139
+ class BeforeAndAfterListener
108
140
{
109
141
private $tokens;
110
142
@@ -132,14 +164,34 @@ event listeners, you can learn more about them at :doc:`/cookbook/service_contai
132
164
}
133
165
}
134
166
}
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
+ }
135
185
}
136
186
137
187
Registering the Listener
138
- ------------------------
188
+ ~~~~~~~~~~~~~~~~~~~~~~~~
139
189
140
190
Finally, register your listener as a service and tag it as an event listener.
141
191
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:
143
195
144
196
.. configuration-block ::
145
197
@@ -148,25 +200,29 @@ your listener to be called just before any controller is executed:
148
200
# app/config/config.yml (or inside your services.yml)
149
201
services :
150
202
demo.tokens.action_listener :
151
- class : Acme\DemoBundle\EventListener\BeforeListener
203
+ class : Acme\DemoBundle\EventListener\BeforeAndAfterListener
152
204
arguments : [ %tokens% ]
153
205
tags :
154
206
- { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
207
+ - { name: kernel.event_listener, event: kernel.response, method: onKernelResponse }
155
208
156
209
.. code-block :: xml
157
210
158
211
<!-- 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 " >
160
213
<argument >%tokens%</argument >
161
214
<tag name =" kernel.event_listener" event =" kernel.controller" method =" onKernelController" />
215
+ <tag name =" kernel.event_listener" event =" kernel.response" method =" onKernelResponse" />
162
216
</service >
163
217
164
218
.. code-block :: php
165
219
166
220
// app/config/config.php (or inside your services.php)
167
221
use Symfony\Component\DependencyInjection\Definition;
168
222
169
- $listener = new Definition('Acme\DemoBundle\EventListener\BeforeListener ', array('%tokens%'));
223
+ $listener = new Definition('Acme\DemoBundle\EventListener\BeforeAndAfterListener ', array('%tokens%'));
170
224
$listener->addTag('kernel.event_listener', array('event' => 'kernel.controller', 'method' => 'onKernelController'));
225
+ $listener->addTag('kernel.event_listener', array('event' => 'kernel.response', 'method' => 'onKernelResponse'));
171
226
$container->setDefinition('demo.tokens.action_listener', $listener);
172
227
228
+
0 commit comments