@@ -67,9 +67,9 @@ parameters key:
67
67
Tag Controllers to Be Checked
68
68
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
69
69
70
- A ``kernel.controller `` listener gets notified on * every * request, right before
71
- the controller is executed. So, first, you need some way to identify if the
72
- controller that matches the request needs token validation.
70
+ A ``kernel.controller `` (aka `` KernelEvents::CONTROLLER ``) listener gets notified
71
+ on * every * request, right before the controller is executed. So, first, you need
72
+ some way to identify if the controller that matches the request needs token validation.
73
73
74
74
A clean and easy way is to create an empty interface and make the controllers
75
75
implement it::
@@ -97,21 +97,23 @@ A controller that implements this interface simply looks like this::
97
97
}
98
98
}
99
99
100
- Creating an Event Listener
101
- ~~~~~~~~~~~~~~~~~~~~~~~~~~
100
+ Creating an Event Subscriber
101
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
102
102
103
103
Next, you'll need to create an event listener, which will hold the logic
104
104
that you want to be executed before your controllers. If you're not familiar with
105
105
event listeners, you can learn more about them at :doc: `/event_dispatcher `::
106
106
107
- // src/AppBundle/EventListener/TokenListener .php
108
- namespace AppBundle\EventListener ;
107
+ // src/AppBundle/EventSubscriber/TokenSubscriber .php
108
+ namespace AppBundle\EventSubscriber ;
109
109
110
110
use AppBundle\Controller\TokenAuthenticatedController;
111
111
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
112
112
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
113
+ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
114
+ use Symfony\Component\HttpKernel\KernelEvents;
113
115
114
- class TokenListener
116
+ class TokenSubscriber implements EventSubscriberInterface
115
117
{
116
118
private $tokens;
117
119
@@ -140,52 +142,28 @@ event listeners, you can learn more about them at :doc:`/event_dispatcher`::
140
142
}
141
143
}
142
144
}
143
- }
144
-
145
- Registering the Listener
146
- ~~~~~~~~~~~~~~~~~~~~~~~~
147
-
148
- Finally, register your listener as a service and tag it as an event listener.
149
- By listening on ``kernel.controller ``, you're telling Symfony that you want
150
- your listener to be called just before any controller is executed.
151
-
152
- .. configuration-block ::
153
-
154
- .. code-block :: yaml
155
145
156
- # app/config/services.yml
157
- services :
158
- app.tokens.action_listener :
159
- class : AppBundle\EventListener\TokenListener
160
- arguments : ['%tokens%']
161
- tags :
162
- - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
163
-
164
- .. code-block :: xml
165
-
166
- <!-- app/config/services.xml -->
167
- <service id =" app.tokens.action_listener" class =" AppBundle\EventListener\TokenListener" >
168
- <argument >%tokens%</argument >
169
- <tag name =" kernel.event_listener" event =" kernel.controller" method =" onKernelController" />
170
- </service >
171
-
172
- .. code-block :: php
146
+ public static function getSubscribedEvents()
147
+ {
148
+ return array(
149
+ KernelEvents::CONTROLLER => 'onKernelController',
150
+ );
151
+ }
152
+ }
173
153
174
- // app/config/services.php
175
- use AppBundle\EventListener\TokenListener;
154
+ That's it! Your ``services.yml `` file should already be setup to load services from
155
+ the ``EventSubscriber `` directory. Symfony takes care of the rest. Your
156
+ ``TokenSubscriber `` ``onKernelController() `` method will be executed on each request.
157
+ If the controller that is about to be executed implements ``TokenAuthenticatedController ``,
158
+ token authentication is applied. This lets you have a "before" filter on any controller
159
+ you want.
176
160
177
- $container->register('app.tokens.action_listener', TokenListener::class)
178
- ->addArgument('%tokens%')
179
- ->addTag('kernel.event_listener', array(
180
- 'event' => 'kernel.controller',
181
- 'method' => 'onKernelController',
182
- ));
161
+ .. tip ::
183
162
184
- With this configuration, your ``TokenListener `` ``onKernelController() `` method
185
- will be executed on each request. If the controller that is about to be executed
186
- implements ``TokenAuthenticatedController ``, token authentication is
187
- applied. This lets you have a "before" filter on any controller that you
188
- want.
163
+ If your subscriber is *not * called on each request, double-check that
164
+ you're :ref: `loading services <service-container-services-load-example >` from
165
+ the ``EventSubscriber `` directory and have :ref: `autoconfigure <services-autoconfigure >`
166
+ enabled. You can also manually add the ``kernel.event_subscriber `` tag.
189
167
190
168
After Filters with the ``kernel.response `` Event
191
169
------------------------------------------------
@@ -195,12 +173,12 @@ can also add a hook that's executed *after* your controller. For this example,
195
173
imagine that you want to add a sha1 hash (with a salt using that token) to
196
174
all responses that have passed this token authentication.
197
175
198
- Another core Symfony event - called ``kernel.response `` - is notified on
199
- every request, but after the controller returns a Response object. Creating
200
- an "after" listener is as easy as creating a listener class and registering
176
+ Another core Symfony event - called ``kernel.response `` (aka `` KernelEvents::RESPONSE ``) -
177
+ is notified on every request, but after the controller returns a Response object.
178
+ Creating an "after" listener is as easy as creating a listener class and registering
201
179
it as a service on this event.
202
180
203
- For example, take the ``TokenListener `` from the previous example and first
181
+ For example, take the ``TokenSubscriber `` from the previous example and first
204
182
record the authentication token inside the request attributes. This will
205
183
serve as a basic flag that this request underwent token authentication::
206
184
@@ -219,9 +197,9 @@ serve as a basic flag that this request underwent token authentication::
219
197
}
220
198
}
221
199
222
- Now, add another method to this class - ``onKernelResponse() `` - that looks
223
- for this flag on the request object and sets a custom header on the response
224
- if it's found::
200
+ Now, configure the subscriber to listen to another event and add ``onKernelResponse() ``.
201
+ This will look for the `` auth_token `` flag on the request object and set a custom
202
+ header on the response if it's found::
225
203
226
204
// add the new use statement at the top of your file
227
205
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
@@ -240,49 +218,16 @@ if it's found::
240
218
$response->headers->set('X-CONTENT-HASH', $hash);
241
219
}
242
220
243
- Finally, a second "tag" is needed in the service definition to notify Symfony
244
- that the ``onKernelResponse `` event should be notified for the ``kernel.response ``
245
- event:
246
-
247
- .. configuration-block ::
248
-
249
- .. code-block :: yaml
250
-
251
- # app/config/services.yml
252
- services :
253
- app.tokens.action_listener :
254
- class : AppBundle\EventListener\TokenListener
255
- arguments : ['%tokens%']
256
- tags :
257
- - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
258
- - { name: kernel.event_listener, event: kernel.response, method: onKernelResponse }
259
-
260
- .. code-block :: xml
261
-
262
- <!-- app/config/services.xml -->
263
- <service id =" app.tokens.action_listener" class =" AppBundle\EventListener\TokenListener" >
264
- <argument >%tokens%</argument >
265
- <tag name =" kernel.event_listener" event =" kernel.controller" method =" onKernelController" />
266
- <tag name =" kernel.event_listener" event =" kernel.response" method =" onKernelResponse" />
267
- </service >
221
+ public static function getSubscribedEvents()
222
+ {
223
+ return array(
224
+ KernelEvents::CONTROLLER => 'onKernelController',
225
+ KernelEvents::RESPONSE => 'onKernelResponse',
226
+ );
227
+ }
268
228
269
- .. code-block :: php
270
229
271
- // app/config/services.php
272
- use AppBundle\EventListener\TokenListener;
273
-
274
- $container->register('app.tokens.action_listener', TokenListener::class)
275
- ->addArgument('%tokens%')
276
- ->addTag('kernel.event_listener', array(
277
- 'event' => 'kernel.controller',
278
- 'method' => 'onKernelController',
279
- ))
280
- ->addTag('kernel.event_listener', array(
281
- 'event' => 'kernel.response',
282
- 'method' => 'onKernelResponse',
283
- ));
284
-
285
- That's it! The ``TokenListener `` is now notified before every controller is
230
+ That's it! The ``TokenSubscriber `` is now notified before every controller is
286
231
executed (``onKernelController() ``) and after every controller returns a response
287
232
(``onKernelResponse() ``). By making specific controllers implement the ``TokenAuthenticatedController ``
288
233
interface, your listener knows which controllers it should take action on.
0 commit comments