【问题标题】:Symfony 5 tests of API endpoints return html with redirectSymfony 5 API 端点测试返回带有重定向的 html
【发布时间】:2021-05-13 06:49:21
【问题描述】:

在从 Symfony 3.4 迁移到 Symfony 5.2 时,我仅在测试中遇到以下问题(在它工作的应用程序中):

  • FOSRest
  • Symfony 5
  • 词汇

fos_rest.yaml

fos_rest:
    body_listener:
        enabled: true
    disable_csrf_role: ROLE_API
    format_listener:
        rules:
            - { path: '^/v1', priorities: [ 'json' ], fallback_format: json, prefer_extension: false }
    zone:
        - { path: ^/v1/* }

security.yaml

api_login:
  pattern: ^/v1/login
  stateless: true
  anonymous: true
  provider: mg_users
  json_login:
    provider: mg_users
    check_path: /v1/login
    require_previous_session: false
    username_path: email
    password_path: password
    success_handler: lexik_jwt_authentication.handler.authentication_success
    failure_handler: lexik_jwt_authentication.handler.authentication_failure

如果我尝试输出响应,针对需要身份验证的 API 端点的功能测试会返回以下输出:

请求

/** @var KernelBrowser $client */
$client = static::createClient();
$client->request(
  'POST',
  '/v1/login',
  [],
  [],
  [
    'CONTENT_TYPE' => 'application/json',
  ],
  '{"email":"admin@email.it","password":"admin"}'
);

回应

<html>
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="refresh" content="0;url='https://local.api.it/v1/login'" />

        <title>Redirecting to https://local.api.it/v1/login</title>
    </head>
    <body>
        Redirecting to <a href="https://local.api.it/v1/login">https://local.api.it/v1/login</a>.
    </body>
</html>

此问题仅出现在需要身份验证的页面/端点中。 如果我使用$client-&gt;followRedirect(),则请求不再包含电子邮件和密码,并且我在 HTML 而不是 JSON 中收到 INVALID JSON 错误。

所以问题:

  • 如何防止被重定向?
  • 为什么它只发生在测试环境中?
  • 我如何才能收到 JSON 错误而不是 HTML?

【问题讨论】:

  • 您确定您的客户正在请求网址https://local.api.it/v1/login 吗?我的第一个猜测是客户端正在请求 http 并被重定向到 https。
  • FormatListener 可能正在覆盖格式请求。您是否尝试过使用application/json 传递Accept 标头($server 参数中的HTTP_ACCEPT)?您是否在测试环境中启用了探查器? JsonLoginAuthenticator 返回truesupport 调用?

标签: php api symfony testing fosrestbundle


【解决方案1】:

json_login 中 username_path 和 password_path 是必需的吗?您可以像这样指定并删除这两个项目:

    providers:
        # used to reload user from session & other features (e.g. switch_user)
        api_entity_provider:
            entity:
                class: App\Entity\YourUserEntity
                property: email

    firewalls:
        dev:
        api_login:
            pattern: ^/v1/login
            stateless: true
            anonymous: true
            provider: api_entity_provider
            json_login:
                check_path: /v1/login
                success_handler: lexik_jwt_authentication.handler.authentication_success
                failure_handler: lexik_jwt_authentication.handler.authentication_failure
                require_previous_session: false

您是否在 access_control 中添加了您的路线:

    access_control:
        - { path: ^/v1/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/v1, roles: IS_AUTHENTICATED_FULLY}

当我查看 https://symfony.com/doc/current/http_client.htmlvendor/symfony/http-client-contracts/HttpClientInterface.php 时,我看到只有 3 个参数,第三个用于选项,而您还有 4 个参数。你在用别的东西吗? 为什么是“CONTENT_TYPE”而不是“content-type”?

这看起来像是我发布了一年半的问题:Symfony 4 / FosREST : API routes return 404

【讨论】:

  • 这是一个 KernelBrowser 客户端。这是一个功能测试。该问题只能在功能测试中重现,而不是在最终应用程序中(有效)
  • 我不知道这个组件,我想我帮不了你了,对不起。
  • 谢谢!!!我被这个问题阻止了,我无法从 Symfony 3.4 迁移到 Symfony 5.... 这真的很令人沮丧:(
【解决方案2】:

我的猜测是检查你的 routes.yaml 文件是否包含我的示例的正确路径

Api_login_check:
  path: /v1/login_check
  methods:  [POST]

以及防火墙下的 security.yaml

login:
            pattern: ^/v1/login_check
            stateless: true
            anonymous: true
            provider: app_user_provider
            json_login:
                check_path: /v1/login_check
                success_handler: lexik_jwt_authentication.handler.authentication_success
                failure_handler: lexik_jwt_authentication.handler.authentication_failure
 

并将您的 FOS_REST 格式侦听器默认为

format_listener:
      rules:
        - { path: '^/v1', priorities: [ 'json', 'html', '*/*' ], fallback_format: json, prefer_extension: true }
        - { path: '^/', priorities: [ 'html', '*/*' ], fallback_format: html, prefer_extension: true }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-19
    • 1970-01-01
    • 2021-08-12
    相关资源
    最近更新 更多