有时候我们可能要求对 访问控制器 前需要检验;这里就用到了 事件机制;
就以验证是否有访问权限控制器为例
首先增加tokens 设置配置用于验证
# app/config/config.yml
parameters:
tokens:
client1: pass1
client2: pass2
定义一个接口来用于区分 不需要验证的控制器
namespace Acme\DemoBundle\Controller;
interface TokenAuthenticatedController
{
// ...
}
namespace Acme\DemoBundle\Controller;
use Acme\DemoBundle\Controller\TokenAuthenticatedController;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class FooController extends Controller implements TokenAuthenticatedController
{
// An action that needs authentication
public function barAction()
{
// ...
}
}
创建 事件监听者(触发事件调用的方法)
// src/Acme/DemoBundle/EventListener/TokenListener.php
namespace Acme\DemoBundle\EventListener;
use Acme\DemoBundle\Controller\TokenAuthenticatedController;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
class TokenListener
{
private $tokens;
public function __construct($tokens)
{
$this->tokens = $tokens;
}
public function onKernelController(FilterControllerEvent $event)
{
$controller = $event->getController();
/*
* $controller passed can be either a class or a Closure. This is not usual in Symfony but it may happen.
* If it is a class, it comes in array format
*/
if (!is_array($controller)) {
return;
}
//<span style="font-family: Arial, Helvetica, sans-serif;">看控制是否需要验证(即是否实现了 </span><span style="font-family: Arial, Helvetica, sans-serif;">TokenAuthenticatedController接口</span><span style="font-family: Arial, Helvetica, sans-serif;">)</span>
if ($controller[0] instanceof TokenAuthenticatedController) {
$token = $event->getRequest()->query->get('token'); //获取闯入的token
if (!in_array($token, $this->tokens)) { //验证token是否正确
throw new AccessDeniedHttpException('This action needs a valid token!');
}
}
}
}
注册监听者成为一个服务
# app/config/config.yml (or inside your services.yml)
services:
demo.tokens.action_listener:
class: Acme\DemoBundle\EventListener\TokenListener
arguments: ["%tokens%"] #传入有效的tokens
tags:
- { name: kernel.event_listener, event: kernel.controller #监听的时间, method: onKernelController #触发调用的方法}
参考手册http://symfony.com/doc/current/cookbook/event_dispatcher/before_after_filters.html