在Symfony中实现简单的静态访问令牌安全验证
无需UserEntity的Symfony极简认证实现
问题背景
刚接触Symfony,希望搭建一个无需使用UserEntity的极简认证示例,现有代码无法正常运行,需要调整使其生效。
核心修改步骤
要实现无UserEntity的认证,关键是提供符合Symfony Security要求的用户对象,并调整令牌处理器逻辑,无需依赖数据库或实体类:
1. 创建极简用户类
在App\Security目录下创建SimpleUser.php,实现Symfony用户接口,无需关联数据库:
<?php namespace App\Security; use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; class SimpleUser implements UserInterface, PasswordAuthenticatedUserInterface { private string $email; public function __construct(string $email) { $this->email = $email; } public function getUserIdentifier(): string { return $this->email; } public function getRoles(): array { // 返回默认角色,可按需调整 return ['ROLE_USER']; } public function eraseCredentials() { // 空实现即可 } // PasswordAuthenticatedUserInterface 要求的方法,此处无需密码返回空字符串 public function getPassword(): string { return ''; } // 可选:若需会话存储用户,实现序列化方法 public function serialize(): string { return serialize($this->email); } public function unserialize(string $serialized): void { $this->email = unserialize($serialized); } }
2. 修改访问令牌处理器
调整AccessTokenHandler.php,使用UserBadge的回调函数直接创建用户对象,无需依赖UserProvider:
<?php namespace App\Security; use Symfony\Component\Security\Http\AccessToken\AccessTokenHandlerInterface; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; class AccessTokenHandler implements AccessTokenHandlerInterface { public function getUserBadgeFrom(string $accessToken): UserBadge { // 示例跳过令牌验证,直接返回固定用户;实际场景可在此处添加token校验逻辑 return new UserBadge('abc@123.com', function() { return new SimpleUser('abc@123.com'); }); } }
3. 调整Security配置
修改config/packages/security.yaml,移除冗余的UserProvider配置,确保donut防火墙配置正确:
security: password_hashers: Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto' firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false main: lazy: true security: false # 若main防火墙无需认证,直接关闭 donut: pattern: ^/donut access_token: token_handler: App\Security\AccessTokenHandler token_extractors: # 指定从请求体的`token`字段提取令牌 request_body: parameter: token access_control: # 限制/donut路径需要认证权限 - { path: ^/donut, roles: ROLE_USER }
4. 控制器代码保留(无需修改)
原控制器可直接使用,getUser()会返回我们创建的SimpleUser对象:
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; class DonutController extends AbstractController { #[Route('/donut', name: 'app_donut', methods: ['POST'])] public function index(Request $request): Response { $user = $this->getUser(); return $this->json([ 'message' => 'Hello there!', 'user_identifier' => $user->getUserIdentifier() ]); } }
验证方法
发送POST请求到/donut,请求体携带token字段(示例无校验,值可任意填写):
curl -X POST http://你的Symfony应用地址/donut -H "Content-Type: application/json" -d '{"token": "任意值"}'
成功响应示例:
{ "message": "Hello there!", "user_identifier": "abc@123.com" }
内容的提问来源于stack exchange,提问作者Umair Khan Jadoon
相关产品推荐
相关产品推荐

