用于验证 JWT 并将 idUser 发送到控制器的 Symfony 4 中间件

Symfony 4 middleware to validate JWT and send the idUser to the controller

在controller之前捕获请求我做过:

public function onKernelController (ControllerEvent $ event)

然后我可以 return 一个错误 (401) 或什么也不做,让它继续到控制器。

$event->getRequest()->attributes->set('id', '33');

我不知道如何将对象作为参数传递给控制器​​。但是主要的问题是这个方法每次请求都会执行2次,不知道为什么

为了验证令牌,我调用了一个微服务。

在 services.yalm 收听这两个事件:

    App\Listener\FirewallTokenController:
    tags:
        - { name: kernel.event_listener, event: kernel.controller }
        
App\Listener\FirewallTokenRequest:
    tags:
        - { name: kernel.event_listener, event: kernel.request }

FirewallTokenRequest 首先运行。您可以在其中检索一个或多个令牌并执行验证。如果令牌正确,我们什么也不做,让执行继续,但如果令牌不正确,我们引入一个自定义错误,我们可以在 FirewallTokenController 中恢复并进行重定向。

如果 FirewallTokenRequest 中的令牌不正确,我们将插入错误:

public function onKernelRequest(RequestEvent $event) {

    $request = $event->getRequest();
    ...
    .....

    if (badToken){
        $request->attributes->set("FirewallTokenEvent", "401");
    } else {
                            
        //Enter the user or any data that is needed in the Controller
        $request->attributes->set("idUser", $idUser);
        $request->attributes->set("email", $email);
        $request->attributes->set("locale", $locale);
    }
}    

我们从 FirewallTokenController 中寻找错误,如果找到它我们可以重定向:

$this->classesExcluded = array("Symfony\Bundle\WebProfilerBundle\Controller\ProfilerController");

public function onKernelController(ControllerEvent $event) {

    $controller = $event->getController(); (deprecated)

    //In each request this class is executed 2 times, this makes it possible to execute it only once.
    if (!is_array($controller) || HttpKernelInterface::MASTER_REQUEST != $event->getRequestType() || in_array(get_class($controller[0]), $this->classesExcluded)) {
        return;
    }


if ($request->attributes->has('FirewallTokenEvent')) {
                
    $response = intval($request->attributes->get('FirewallTokenEvent'));
                
    if ($response == 401) {   //Unathorizated
                    
        $redirectUrl = 'unauthorized';
        $event->setController(function () use($redirectUrl) {
              return new RedirectResponse($redirectUrl);
        });

}

从控制器检索在 FirewallTokenRequest 中输入的用户(或任何数据):

$idUser = intval($request->attributes->get('idUser'));
$email = $request->attributes->get('email');
$locale = $request->attributes->get('locale');