为什么我的 jwt 令牌永不过期? [英] Why my jwt tokens never expire?

查看:236
本文介绍了为什么我的 jwt 令牌永不过期?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我继承了一个使用这个控制器来验证用户身份的 Symfony 项目:

I've inherited a Symfony project that uses this controller to authenticate users:

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 秒过期.所以,按照文档,我添加了这个监听器.

And the customer requests an update: token should expire 10 seconds after the login. So, following the documentation, I added this listener.

<?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);
    }
}

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

And, of course, I've marked the listener to observe the event

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 似乎不起作用.

If I get a token with Postman and use it to make following requests I can make those request for days and days. The token never expire. My JWTCreatedListener does not seem to work.

怎么了?

推荐答案

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

They never expire because you are using a low level api which is the JWT encoder. As you can see (since you call it), encode() takes the payload. For getting token expiration, the payload must contain the exp claim with the expiration timestamp as value.
This is handled by the lexik_jwt_authentication.jwt_manager service which uses the value of the lexik_jwt_authentication.encoder.token_ttl config option to determine the expiration date. Set it and uses $this->get('lexik_jwt_authentication.jwt_manager')->create($user) for creating the token, then $this->get('lexik_jwt_authentication.jwt_manager')->decode($token) at time to decode/verify it.

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

Note that for using this bundle properly (allowing to hook into all the events it provides), you should consider using proper security configuration (as shown in the README) instead of doing this by hand in your controller.

这篇关于为什么我的 jwt 令牌永不过期?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆