You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 20:53:14