You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

未添加CSRF Token的Rails表单为何能正常工作?

问题:未添加CSRF Token的表单仍能正常提交,原因是什么?

相关代码

HTML表单

<form accept-charset="UTF-8" action="/users" method="post">
  <label for="username">Username:</label>
  <input type="text" id="username" name="user[username]">
  <br>

  <label for="email">Email:</label>
  <input type="text" id="email" name="user[email]">
  <br>

  <label for="password">Password:</label>
  <input type="password" id="password" name="user[password]">

  <input type="submit" value="Submit">
</form>

Rails控制器代码

def create
  @user = User.new(user_params)

  if @user.save
    redirect_to new_user_path
  else
    render :new, status: :unprocessable_entity
  end
end

private

def user_params
  params.require(:user).permit(:username, :email, :password)
end

请求参数

#<ActionController::Parameters {"user"=>{"username"=>"username", "email"=>"email", "password"=>"password"}, "controller"=>"users", "action"=>"create"} permitted: false>

核心原因分析

正常情况下,Rails默认会强制校验POST/PUT/PATCH/DELETE请求的CSRF Token,未添加Token的表单应该会被拦截并抛出ActionController::InvalidAuthenticityToken异常。能正常提交的情况,通常是以下几种:

  1. CSRF保护未启用
    Rails的ApplicationController默认包含protect_from_forgery with: :exception来开启防护,如果这条代码被注释,或者你的UsersController通过skip_before_action :verify_authenticity_token主动跳过了CSRF验证,表单提交就不会被拦截。

  2. 环境配置关闭了CSRF检查
    如果你在config/environments/development.rb里设置了config.action_controller.allow_forgery_protection = false,开发环境下会直接关闭CSRF校验,这种设置一般用于调试,但上线前必须改回默认值(true)。

  3. 第三方gem或工具禁用了校验
    部分API开发相关的gem(比如devise_token_auth)或者调试工具,可能会自动添加skip_before_action :verify_authenticity_token,导致CSRF校验被绕过。

注意事项

CSRF保护是防止跨站请求伪造的关键机制,即使当前表单能正常提交,也必须补上Token。手写HTML表单时,可通过以下方式添加:

  1. 在页面头部添加<%= csrf_meta_tags %>生成meta标签
  2. 在表单内添加隐藏字段:
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>">

内容的提问来源于stack exchange,提问作者vladislav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 22:15:29