升级Rails到6.1后为何仅GraphQL控制器需配置skip_forgery_protection?
Rails升级后仅GraphQL控制器触发CSRF报错的可能原因
你提到的CSRF保护仅对POST、PUT、PATCH、DELETE等修改类请求生效的猜想是正确的,除此之外还有以下几个常见原因会导致其余控制器未触发报错:
- 请求方法差异:Rails内置的
protect_from_forgery默认仅校验会触发服务端状态变更的HTTP请求方法,GET、HEAD这类只读请求默认不会执行CSRF校验,如果你其余控制器的测试和手动操作都是基于GET请求,自然不会触发报错。 - 请求内容类型差异:Rails的CSRF保护默认仅针对浏览器表单提交的场景生效,也就是Content-Type为
application/x-www-form-urlencoded、multipart/form-data或者text/html的请求会触发校验,JSON、XML等API类请求默认不会触发CSRF校验。如果你的其他控制器接口都是JSON格式的API,而GraphQL接口刚好是用表单格式提交请求,就会出现只有GraphQL控制器触发校验的情况。 - 测试环境配置差异:Rails默认的测试环境配置中,通常会设置
config.action_controller.allow_forgery_protection = false关闭全局CSRF校验,如果你GraphQL的测试用例特殊模拟了浏览器表单提交的场景,或者手动修改了测试配置开启了对应请求的校验,也会仅在GraphQL侧出现报错。 - 全局跳过逻辑:检查ApplicationController中是否存在条件跳过CSRF校验的逻辑,比如常见的全局配置
skip_forgery_protection if: -> { request.format.json? },这类逻辑会让所有JSON请求跳过校验,仅符合特定条件的请求(比如GraphQL的表单提交请求)会触发校验。
内容的提问来源于stack exchange,提问作者John Bachir
相关产品推荐
相关产品推荐

