symfony中使用jwt解决多个用户实体里同一账号冲突问题 langziyang Symfony博客 297 views 在做前后端分离的时候,如果你不是使用cookie而是jwt来做认证,并且如果你用两张表来表示管理员以及客户,同时又出现同一个账号同时存在于两张表中的话。 奇葩的问题就出现了, 比如说我们有一个Employee和Customer的实体: ```php class Employee implements UserInterface, PasswordAuthenticatedUserInterface { // other code public function getUserIdentifier(): string { return (string)$this->username; } } ``` ```php class Customer implements UserInterface, PasswordAuthenticatedUserInterface { // other code public function getUserIdentifier(): string { return (string)$this->username; } } ``` 可以看到,在Employee和Customer中,都使用唯一的username来表示身份,普通登录时,用username和password来认证。 在symfony的防火墙中,一个防火墙要认证两个表,则使用chain来做链式认证. ```yaml security: providers: app_employee_provider: entity: class: App\Entity\Employee property: username app_customer_provider: entity: class: App\Entity\Customer property: username chain_provider: chain: providers: ['app_employee_provider','app_customer_provider'] firewalls: api: pattern: ^/api stateless: true provider: chain_provider jwt: ~ ``` 可以看到在api防火墙下我使用了chain_provider来认证两张表中的用户,因为/api下的所有接口所有人都可以访问。 这个时候如果你登录Customer表中的用户,取得token后,把token发送到接口,然后你用Symfony\Bundle\SecurityBundle\Security组件去取当前登录的用户 就会发现用户是Employee表中同名用户,因为认证时先用app_employee_provider中查到这个用户,查不到就继续查app_customer_provider,如果在 app_employee_provider中查到了就使用该表中的用户。当然你可以交换chain_provider中的顺序,可同样的问题依然会出现在同名的管理员身上。 这个时候我们只需要修改一下chain_provider里的代码就可以完美解决: ```yaml chain_provider: lexik_jwt: class: Lexik\Bundle\JWTAuthenticationBundle\Security\User\JWTUser ``` 然后无论你怎么登录,当前用户始终都是token所表示的那个用户了。 帮助PHPZlc项目! 与任何开源项目一样, 贡献代码 或 文档 是最常见的帮助方式, 但我们也有广泛的 赞助机会。 2 赞赏 加入技术群 评论 去登录