API 平台禁用重定向登录

我正在使用 Symfony 4 和 API 平台开发一个网站。我的用户资源受到标准 Symfony 安全性 ( "security": "is_granted('ROLE_USER')") 的保护:


/**

* @ORM\Entity(repositoryClass="App\Repository\UserRepository")

* @ApiResource(

*     collectionOperations={

*         "get_user_profile": {

*             "method": "GET",

*             "path": "/users/profile",

*             "controller": GetUserProfile::class,

*             "pagination_enabled": false,

*             "openapi_context": {"summary": "Retrieves the current User's profile."},

*             "security": "is_granted('ROLE_USER')"

*         },

*     },

*     itemOperations={},

*     normalizationContext={"groups": {"read"}},

* )

*/

class User implements UserInterface

{

}

问题是,如果我尝试访问此 API,则响应将重定向到登录页面。如何禁用重定向并将响应保留为 401?


重定向对网站用户非常有用,但 API 用户不应该收到 HTML 响应。


这是我的security.yml:


security:

    encoders:

        App\Entity\User:

            algorithm: auto


    # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers

    providers:

        # used to reload user from session & other features (e.g. switch_user)

        app_user_provider:

            entity:

                class: App\Entity\User

                property: username

    firewalls:

        dev:

            pattern: ^/(_(profiler|wdt)|css|img|js)/

            security: false

        main:

            anonymous: lazy

            guard:

                authenticators:

                    - App\Security\LoginFormAuthenticator

            logout:

                path: app_logout

                # where to redirect after logout

                # target: app_any_route


            remember_me:

                secret:   '%kernel.secret%'

                lifetime: 604800 # 1 week in seconds

                path:     /


            # activate different ways to authenticate

            # https://symfony.com/doc/current/security.html#firewalls-authentication


            # https://symfony.com/doc/current/security/impersonating_user.html

            # switch_user: true



噜噜哒
浏览 90回答 1
1回答

红糖糍粑

问题是您只有一个保护身份验证器,并且该身份验证器是 LoginFormAuthenticator,它在AbstractFormLoginAuthenticator.这个抽象类很方便,但它被认为是用于常规 Web 客户端,而不是用于 API 流。如果你检查它的start()方法,你会发现:    /**     * Override to control what happens when the user hits a secure page     * but isn't logged in yet.     *     * @return RedirectResponse     */    public function start(Request $request, AuthenticationException $authException = null)    {        $url = $this->getLoginUrl();        return new RedirectResponse($url);    }因此,只要经过身份验证的请求命中,它就会得到这个重定向响应。您的选择是:便宜又容易:覆盖start(),LoginFormAuthenticator因此它返回如下内容:return new JsonReponse(    ['status' => 'KO', 'message' => 'Unauthorized'],    Response::HTTP_UNAUTHORIZED]);这将返回一个带有 401 的 JSON 和所有未经授权的请求。但是“常规”网络请求不会被重定向到登录表单。这并不理想。稍微好一些:检查start()请求是否具有application/*内容类型,并在这些内容上返回 401,但将其余部分重定向到登录表单。你实际上应该做的事情:API URL 应该由不同于常规 Web 路径的保护身份验证器保护。为与 API 无关的流量保留登录表单。Api-Platform 包内置了对 JWT 身份验证的支持。只需使用它,它很容易实现。
打开App,查看更多内容
随时随地看视频慕课网APP