Why my jwt tokens never expire?

做~自己de王妃 提交于 2020-01-02 12:21:13

问题


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

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 }

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.

What's wrong?


回答1:


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.




回答2:


The key is here:

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

I need to add another parameter to encode function:

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


来源:https://stackoverflow.com/questions/45914601/why-my-jwt-tokens-never-expire

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!