symfony – LexikJWTAuthenticationBundle在匿名路由上返回401无效令牌

我正在使用这个LexikJWTAuthenticationBundle和FosUserBundle.

我在security.yml中有这个:

firewalls:
    app:
        pattern: ^/api
        stateless: true
        anonymous: true
        lexik_jwt: ~

使用以下access_control:

- { path: ^/api/user/action1, roles: IS_AUTHENTICATED_FULLY }
- { path: ^/api/user/action2, roles: IS_AUTHENTICATED_ANONYMOUSLY }

无论请求标头内部是什么,我期望/ api / user / action2的行为都具有访问权限.但是,如果授权承载已设置但无效,我将获得401(可以使用有效令牌或根本没有授权承载).

我的用例是我需要在我的控制器中检查用户是否已登录,但如果没有,我仍然希望让匿名用户访问该路由.

最佳答案 您必须为要允许匿名用户的路由/模式创建特定防火墙:

action2:
    pattern: ^/api/user/action2
    anonymous: true
    lexik_jwt: ~

然后,只需在完全受保护之前移动受保护较少的access_control:

- { path: ^/api/user/action2, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/user/action1, roles: IS_AUTHENTICATED_FULLY }

通过这种方式,您应用程序不关心Authorization标头,并且所有用户都可以在没有JWT的情况下访问资源.

更新

将匿名路由的防火墙更改为:

action2:
    pattern: ^/api/user/action2
    anonymous: true
    lexik_jwt: ~

并使access_control接受匿名且经过完全身份验证的用户:

- { path: ^/api/user/action2, roles: [IS_AUTHENTICATED_ANONYMOUSLY, IS_AUTHENTICATED_FULLY]  }
- { path: ^/api/user/action1, roles: IS_AUTHENTICATED_FULLY }

请使用相同的订单并正确清除缓存.

它在我的JWT / FOSUB应用程序中运行良好,如果它不适合你,我会给你一个现成的工作示例.

和控制器:

$currentToken = $this->get('security.token_storage')->getToken();

if (is_object($currentToken->getUser())) {
    // Do your logic with the current user
    return new JsonResponse(['user' => $currentToken->getUser()->getUsername()]);
} else {
    return new JsonResponse(['user' => 'Anonymous']);
}

希望对你有效.

点赞