覆盖 rails authenticity_token 设置

overriding rails authenticity_token setting

提交表单需要接收服务器命名为 authenticity_token 的令牌,并且需要一个只有发布和接收服务器知道的字符串:

<input id="authenticity_token" name="authenticity_token" type="hidden" value="ac513de198a9f0536df5003fb5ba3122d1ee53d5" />

如果我调用实例或全局变量,该值将呈现。但是,即使控制器设置了以下过滤器:

  skip_before_action :verify_authenticity_token, only: [:reservation]

要不要试试

<%= form_tag('https://test.webten.net/form') do %>
<%= hidden_field_tag :authenticity_token, @ppayment.authenticity_token, id: "authenticity_token" %>

<%= tag(:input, type: "hidden", name: request_forgery_protection_token.to_s, value: @ppayment.authenticity_token) %>

<input id="" name="authenticity_token" type="hidden" value="ac513de198a9f0536df5003fb5ba3122d1ee53d5" />

Rails 最终使用自己的会话设置值和渲染来压缩每个值:

<input type="hidden" name="authenticity_token" id="authenticity_token" value="ydi5En1ywUkN5VsYIBXu6JTbQmXtwxNhpKlyjbbLi3RdvCc+A59EdDZvroGsGFplAAE5ATLcSqw25LVQkyPtKw==">
<input type="hidden" name="authenticity_token" value="ydi5En1ywUkN5VsYIBXu6JTbQmXtwxNhpKlyjbbLi3RdvCc+A59EdDZvroGsGFplAAE5ATLcSqw25LVQkyPtKw==">
<input id="authenticity_token" name="authenticity_token" type="hidden" value="ydi5En1ywUkN5VsYIBXu6JTbQmXtwxNhpKlyjbbLi3RdvCc+A59EdDZvroGsGFplAAE5ATLcSqw25LVQkyPtKw==">

如何在此控制器操作中覆盖 rails 默认行为?

您必须覆盖 form_tag 调用中的 :authenticity_token 参数,以防止 Rails 默认添加会话的真实性令牌:

<%= form_tag('https://test.webten.net/form', authenticity_token: 'ac513de198a9f0536df5003fb5ba3122d1ee53d5') do %>

或:

<%= form_tag('https://test.webten.net/form', authenticity_token: false) do %>
  <%= hidden_field_tag 'authenticity_token', 'ac513de198a9f0536df5003fb5ba3122d1ee53d5' %>

如果这不起作用,您可能有一些 JS 覆盖了您从 META 标签中提供的真实性令牌。在您的 JS 中搜索 'csrf-token'。

有关详细信息,请参阅 http://guides.rubyonrails.org/form_helpers.html#forms-to-external-resources

[这个答案是对前一个答案的补充。它解决了这个问题,但是以一种不优雅的方式]

各种可能的解决方案似乎不完整/偏离目标

  • form_authenticity_token是 returns 当前的视图助手 session 的真实性令牌。为时已晚 布局可能已经调用它
  • most voted response 有一个 per action 方法 protect_from_forgery 出于内部目的忽略它。仍然 太晚了,因为 session 已经发布了
  • a skip before action 也和之前的解决方案一样 晚了,session 令牌已发行
  • rails guide 的表述不正确:authenticity_token: 'external_token'

Aaron Breckenridge的回答提供了一个线索:"you probably have some JS that overwrites the authenticity token ",得到this posting的支持。因此,可以搜索应用程序目录的内容,但仍然找不到 JS 处理程序...例如,当 jquery-ujs 安装了 gem 时。根据观察到的行为,它必须在每次遇到 name='authenticity-token' 时被激发并根据 META 标签设置值(合乎逻辑。为什么在同一页面上有 2 个不同的标记......) - 正确地完成它的工作!

从字面上看,该令牌不得在上游生成。所以修改布局的 header 部分:

<% unless  request.path == "/controller/action" %>
  <%= csrf_meta_tags %>
<% end %>

是一个可行的解决方案。此解决方案获得 pollution-prone 多个路径。另一个需要多个布局处理...因此,文件在 'kludgey' 下。 (愿意招待更好的!)