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

Symfony 7:如何让公开路由跳过提前触发的access_token.token_handler?

Symfony 7 中让公开路由跳过 AccessTokenHandler 验证的方案

问题背景

使用AccessTokenHandler处理令牌验证,但PUBLIC_ACCESS标记的路由(示例中为/auth前缀)无需验证。但Symfony的access_token处理器会在access_control规则之前触发,导致公开路由也会执行令牌验证逻辑,需要解决这一冲突。

最优解决方案:拆分防火墙

这是最符合Symfony安全组件设计逻辑的方案,将公开路由与需要验证的路由分配到不同防火墙,让公开路由的防火墙完全跳过安全验证流程。

修改security.yaml配置如下:

# security.yaml
firewalls:
    # 公开路由专用防火墙,关闭安全验证
    public:
        pattern: ^/auth
        security: false
    # 需令牌验证的主防火墙
    main:
        pattern: ^/
        json_login:
            check_path: sign_in
            username_path: email
            password_path: password
        access_token:
            token_handler: App\Security\AccessTokenHandler

access_control:
    - { path: ^/auth, roles: PUBLIC_ACCESS }
    - { path: ^/*, roles: ROLE_USER }
  • security: false会让/auth前缀的路由完全跳过所有安全验证步骤,自然不会触发AccessTokenHandler
  • 主防火墙main匹配其余所有路由,正常执行令牌验证逻辑

备选方案:在AccessTokenHandler中判断请求路径

如果无法拆分防火墙,可以在处理器中注入RequestStack,判断当前请求是否属于公开路由,若是则直接返回匿名用户徽章以跳过令牌验证。

修改AccessTokenHandler.php代码如下:

# AccessTokenHandler.php
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Security\Core\User\AnonymousUser;

readonly class AccessTokenHandler implements AccessTokenHandlerInterface
{
    public function __construct(
        private ApiTokenRepository $repository,
        private RequestStack $requestStack
    ) {
    }

    public function getUserBadgeFrom(string $accessToken): UserBadge
    {
        $request = $this->requestStack->getCurrentRequest();
        // 匹配公开路由前缀
        if ($request && str_starts_with($request->getPathInfo(), '/auth')) {
            // 返回匿名用户徽章,跳过令牌验证
            return new UserBadge('anon.', fn() => new AnonymousUser());
        }

        $accessTokenEntity = $this->repository->findOneByValue($accessToken);
        if (is_null($accessTokenEntity) || !$accessTokenEntity->isValid()) {
            throw new BadCredentialsException('Invalid credentials.');
        }

        return new UserBadge($accessTokenEntity->getUser()->getUserIdentifier());
    }
}
  • 该方案通过在处理器内部判断路由实现需求,但逻辑耦合度更高,仅适合无法拆分防火墙的场景

内容的提问来源于stack exchange,提问作者Oleg Vartanov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 06:25:04