Rails 求教一个有关 csrf_meta_tags 的疑问

yeerkunth · 2013年08月29日 · 最后由 yeerkunth 回复于 2013年08月29日 · 6501 次阅读

在 app/views/layouts/application.html.erb 里面有一句 <%= csrf_meta_tags %>

<head>
  <title>Monkey App | <%= yield(:title) %></title>
  <%= stylesheet_link_tag    "application", media: "all", "data-turbolinks-track" => true %>
  <%= javascript_include_tag "application", "data-turbolinks-track" => true %>
  <%= csrf_meta_tags %>
</head>

它会生成下面的 html header

<meta content="authenticity_token" name="csrf-param">
<meta content="6dzSP5yGThFu4v6hiXdROKQtIfle+5Seeb60hQgmZGU=" name="csrf-token">

我的问题是,它在什么地方用到了?

看 rails 对 csrf token 验证的代码好像只针对来自 Form 的 params 的 token 和 http 头的 token 有做处理. meta 里面的东西貌似没被用到?

~/.rvm/gems/ruby-2.0.0-p247/gems/actionpack-4.0.0/lib/action_controller/metal/request_forgery_protection.rb

# Returns true or false if a request is verified. Checks:
#
# * is it a GET or HEAD request?  Gets should be safe and idempotent
# * Does the form_authenticity_token match the given token value from the params?
# * Does the X-CSRF-Token header match the form_authenticity_token
def verified_request?
  !protect_against_forgery? || request.get? || request.head? ||
    form_authenticity_token == params[request_forgery_protection_token] ||
    form_authenticity_token == request.headers['X-CSRF-Token']
end

貌似明白了,它是用了中转的.. jquery 会利用它来填充 http header. 也就是说 X-CSRF-Token 就是从这个 meta 来的

// Make sure that every Ajax request sends the CSRF token
CSRFProtection: function(xhr) {
  var token = $('meta[name="csrf-token"]').attr('content');
  if (token) xhr.setRequestHeader('X-CSRF-Token', token);
},
需要 登陆 后方可回复, 如果你还没有账号请 注册新账号