php 使用LexikJWTEuthenticationBundle生成短生命周期的JWT令牌

mrphzbgm  于 2023-05-16  发布在  PHP
关注(0)|答案(1)|浏览(130)

我尝试通过Symfony保护一些文件。假设我通过以下URL访问它们:
https://test.com/file/?token=AAAABBBBCCCC
我已经通过LexikJWTAuthenticationBundle实现了授权。我登录;得到一个访问令牌--这工作得很好。所以我使用我的登录访问令牌来输入URL。
但是登录令牌的寿命太长了。因此,我考虑创建一个短生命周期令牌(< 2秒),只访问文件一次。只要我刷新页面,对文件的访问就应该消失了。
在symfony页面上,我发现了如何创建令牌:$JWTManager->create($user)https://symfony.com/bundles/LexikJWTAuthenticationBundle/current/7-manual-token-creation.html
但是我无法配置此令牌的寿命。这通常在lexik_jwt_authentication.yaml中配置,但我不想更改登录令牌的寿命:/
使用Symfony 5
有什么想法吗

6jjcrrmo

6jjcrrmo1#

我现在解决了。首先创建一个令牌并添加任何数据以标识其用例。例如,我使用一个scoped:

public function createToken(JWTTokenManagerInterface $jwt): JsonResponse
{
    $token = $jwt->createFromPayload(
        $this->getUser(),
        ['scope' => 'fileScope']
    );

    return new JsonResponse($token);
}

然后使用EventListener根据作用域设置到期日期:

// EventListener/JWTCreatedListener.php

declare(strict_types=1);

namespace App\EventListener;

use App\Controller\Authentication\GetDocumentFileToken;
use Lexik\Bundle\JWTAuthenticationBundle\Event\JWTCreatedEvent;

/**
 * Class JWTCreatedListener
 */
class JWTCreatedListener
{
    /**
     * @param JWTCreatedEvent $event
     *
     * @return void
     */
    public function onJWTCreated(JWTCreatedEvent $event): void
    {
        $payload = $event->getData();

        if (($payload['scope'] ?? '') === 'fileScope') {
            $expiration = new \DateTime('+1 minute');
            $payload['exp'] = $expiration->getTimestamp();
        }

        $event->setData($payload);
    }
}

然后,在只允许特定范围令牌的控制器中:

public function getDocumentFile(JWTTokenManagerInterface $jwt): JsonResponse
{
    $token = /* Get token from request or something */;
    $tokenData = $jwt->parse($token);

    if (($tokenData['scope'] ?? '') !== 'fileScope') {
        return new JsonResponse('Permission denied', 400);
    }

    // Token is valid and fileScope so output file
}

相关问题