【问题标题】:Why my jwt tokens never expire?为什么我的 jwt 令牌永不过期?
【发布时间】:2018-02-05 11:07:53
【问题描述】:

我继承了一个使用此控制器对用户进行身份验证的 Symfony 项目:

class TokenController extends FOSRestController
{
    public function postTokensAction(Request $request)
    {
        $username = $request->request->get('username');
        $password = $request->request->get('password');

        $user = $this->get('fos_user.user_manager')
                     ->findUserByUsername($username);

        if (!$user) {
            throw $this->createNotFoundException();
        }

        $passwordEncoder = $this->get('security.password_encoder');
        if(!$passwordEncoder->isPasswordValid($user, $password)) {
            throw $this->createAccessDeniedException();
        }

        $groups = ['foo', 'bar'];
        $context = SerializationContext::create()
                       ->setGroups($groups);

        $token = $this->get('lexik_jwt_authentication.encoder')
                      ->encode(['username' => $user->getUsername()]);

        $user = $this->get('jms_serializer')
                     ->toArray($user, $context);

        return new JsonResponse([
            'token' => $token,
            'user' => $user
        ]);
    }
}

客户要求更新:令牌应在登录后 10 秒过期。所以,按照文档,我添加了这个监听器。

<?php

namespace AppBundle\EventListener;

use Lexik\Bundle\JWTAuthenticationBundle\Event\JWTCreatedEvent;

class JWTCreatedListener
{
    public function onJWTCreated(JWTCreatedEvent $event)
    {
        $expiration = new \DateTime('now');
        $expiration->add(new \DateInterval('PT10S'));
        $payload = $event->getData();
        $payload['exp'] = $expiration->getTimestamp();
        $event->setData($payload);
    }
}

当然,我已经标记了监听器来观察事件

acme_api.event.jwt_created_listener:
    class: AppBundle\EventListener\JWTCreatedListener
    tags:
        - { name: kernel.event_listener, event: lexik_jwt_authentication.on_jwt_created, method: onJWTCreated }

如果我通过 Postman 获得令牌并使用它来发出以下请求,我可以在几天和几天内发出这些请求。令牌永不过期。我的 JWTCreatedListener 似乎不起作用。

怎么了?

【问题讨论】:

标签: symfony lexikjwtauthbundle


【解决方案1】:

它们永远不会过期,因为您使用的是 JWT 编码器的低级 API。如您所见(因为您调用它),encode() 获取有效负载。 要获得令牌过期,有效负载必须包含 exp 声明,并以过期时间戳作为值。
这由lexik_jwt_authentication.jwt_manager 服务处理,该服务使用lexik_jwt_authentication.encoder.token_ttl 配置选项的值来确定到期日期。设置它并使用$this-&gt;get('lexik_jwt_authentication.jwt_manager')-&gt;create($user) 创建令牌,然后使用$this-&gt;get('lexik_jwt_authentication.jwt_manager')-&gt;decode($token) 解码/验证它。

请注意,要正确使用此捆绑包(允许挂钩它提供的所有事件),您应该考虑使用正确的安全配置(如自述文件中所示),而不是在控制器中手动执行此操作。

【讨论】:

    【解决方案2】:

    关键在这里:

    $token = $this->get('lexik_jwt_authentication.encoder')
                  ->encode(['username' => $user->getUsername()]);
    

    我需要添加另一个参数来编码函数:

    $token = $this->get('lexik_jwt_authentication.encoder')
                  ->encode([
                      'username' => $user->getUsername(),
                      'exp'      => (new \DateTime('+30 minute'))->getTimestamp(),
                  ]);
    

    【讨论】:

    • lexik_jwt_authentication.encoder.token_ttl和encode方法中的'exp'key有什么区别?
    猜你喜欢
    • 2021-10-03
    • 2021-07-25
    • 2020-01-15
    • 2017-03-04
    • 2019-07-04
    • 2020-04-07
    • 2017-03-01
    • 1970-01-01
    • 2014-04-14
    相关资源
    最近更新 更多