Symfony 3.4迁移至5.2:测试环境下API认证接口返回HTML重定向的问题排查
我之前从Symfony 3.4迁移到5.x时也碰到过几乎一模一样的测试环境专属问题,结合你的配置和测试代码,给你逐个解答疑问:
1. 如何阻止该重定向行为?
重定向的核心原因大概率是测试环境中发起的HTTP请求被Symfony强制转到HTTPS,而生产环境请求本身就是HTTPS所以没问题。你可以通过以下两种方式解决:
方式一:在测试请求中模拟HTTPS环境
修改测试代码,给请求头添加HTTPS: on标识,让Symfony认为这是HTTPS请求,避免触发重定向:
/** @var KernelBrowser $client */ $client = static::createClient(); $client->request( 'POST', '/v1/login', [], [], [ 'CONTENT_TYPE' => 'application/json', 'HTTPS' => 'on', // 关键:模拟HTTPS请求 ], '{"email":"admin@email.it","password":"admin"}' );
方式二:修改测试环境的路由配置
检查config/packages/test/framework.yaml中的路由上下文配置,如果设置了scheme: https,可以临时注释或改为http,避免Symfony强制重定向:
framework: router: request_context: # scheme: https # 注释掉这行或者改为http
2. 为何该问题仅在测试环境出现?
原因很直白:
- 生产环境:部署的应用通常会通过Nginx/Apache配置强制HTTPS,所有请求都是以HTTPS方式发起的,Symfony不会触发重定向逻辑。
- 测试环境:我们用
KernelBrowser直接调用Symfony内核发起请求,默认是HTTP协议。如果测试环境配置中(比如framework.yaml的router上下文、或者Security的access_control规则)设置了强制HTTPS,Symfony就会返回HTML格式的301/302重定向响应,让浏览器跳转到HTTPS地址——这就是你看到的HTML页面的来源。
3. 如何使接口返回JSON格式的错误响应而非HTML?
解决重定向问题后,还需要确保FOSRest和Lexik JWT的配置正确生效,让异常和认证错误以JSON格式返回:
步骤一:完善FOSRest的异常处理配置
在config/packages/fos_rest.yaml中添加异常监听和视图配置,确保所有API请求的异常都被转换成JSON:
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/* } # 新增以下配置 exception: enabled: true exception_controller: 'fos_rest.exception.controller:showAction' view: view_response_listener: 'force' formats: json: true
步骤二:确保测试环境的FOSRest配置和生产环境一致
检查config/packages/test/fos_rest.yaml,不要覆盖生产环境的format_listener或exception配置,否则测试环境下FOSRest的JSON转换逻辑会失效。
步骤三:验证Lexik JWT的处理器配置
确认security.yaml中json_login的success_handler和failure_handler都是Lexik JWT提供的处理器,这些处理器默认会返回JSON格式的响应:
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端点时,无论是成功还是失败,都会返回JSON格式的响应,再也不会出现HTML重定向了。
内容的提问来源于stack exchange,提问作者MrDevel

