跳到内容

无数据库用户提供器

编辑此页

来自 jwt.io

自包含:有效负载包含关于用户的所有必要信息,避免了多次查询数据库的需求。 https://jwt.node.org.cn/introduction

JWT 是自包含的,这意味着我们可以信任其有效负载来处理身份验证。简而言之,当验证 JWT 令牌时,应该不需要从数据库加载用户,数据库应该只在交付令牌时被访问一次。

这就是为什么我们决定提供一个用户提供器,它可以从 JWT 有效负载创建 User 实例。

配置用户提供器

为了工作,提供器只需要几行配置

1
2
3
4
5
# config/packages/security.yaml
security:
    providers:
        jwt:
            lexik_jwt: ~

然后,在你的 JWT 保护的防火墙上使用它

1
2
3
4
5
6
# config/packages/security.yaml
security:
    firewalls:
        api:
            provider: jwt
            jwt: ~

它改变了什么?

现在提供器已经配置好了,当验证令牌时,JWTAuthenticator 将自动使用它。不是从“数据存储”(即内存或任何数据库引擎)加载用户,而是从 JWT 有效负载创建一个 JWTUserInterface 实例,它将被缓存用于请求并进行身份验证。我们提供了一个简单的 JWTUser 类来实现这个接口,当配置提供器时,默认使用它。

我可以使用我自己的用户类吗?

当然,你可以。你只需要让你的用户类实现 JWTUserInterface 接口。这个接口只包含一个 createFromPayload() 命名构造函数,它接受用户的用户名和 JWT 令牌有效负载作为参数,并返回该类的一个实例。

示例实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
namespace App\Security;

final class User implements JWTUserInterface
{
    // Your own logic

    public function __construct($username, array $roles, $email)
    {
        $this->username = $username;
        $this->roles = $roles;
        $this->email = $email;
    }

    public static function createFromPayload($username, array $payload)
    {
        return new self(
            $username,
            $payload['roles'], // Added by default
            $payload['email']  // Custom
        );
    }
}

注意

如果默认的 JWTUser 类符合你的需求,你可以扩展它。

配置

1
2
3
4
5
6
# config/packages/security.yaml
providers:
    # ...
    jwt:
        lexik_jwt:
            class: App\Security\User

瞧!

这项工作,包括代码示例,根据 Creative Commons BY-SA 3.0 许可证获得许可。
目录
    版本