【问题标题】:Symfony 4 middleware to validate JWT and send the idUser to the controllerSymfony 4 中间件验证 JWT 并将 idUser 发送到控制器
【发布时间】:2020-07-16 21:35:50
【问题描述】:

在我已经完成的控制器之前捕获请求:

public function onKernelController (ControllerEvent $ event)

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

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

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

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

【问题讨论】:

  • 为什么不呢?您可以访问实际的控制器实例,因此您可以在其上调用 set 方法。一种耦合度较低的方法可能是将您的信息作为属性添加到请求对象中。
  • 为什么不利用 Symfony 安全组件来验证 JWT 令牌?验证后,在控制器中设置并访问用户。您可以使用以下捆绑包:github.com/lexik/LexikJWTAuthenticationBundle
  • 我认为您拥有安全组件symfony.com/doc/current/security.html 中所需的所有工具,您可以使用安全注释来保护您的操作,而无需创建自己的 onKernelRequest

标签: symfony jwt middleware


【解决方案1】:

在 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');

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-06
    • 2019-01-25
    • 2020-03-25
    • 1970-01-01
    • 1970-01-01
    • 2021-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多