Phoenix忽略了csrf_token的ajax请求

时间:2017-10-23 00:09:18

标签: ajax elixir csrf phoenix-framework

我有这个ajax请求:

//..............
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-type", "application/json;charset=UTF-8");
xhr.setRequestHeader("x-csrf-token", document.querySelector("meta[name=csrf]").content);
xhr.send(JSON.stringify(data));

在页面上有Phoenix生成的csrf令牌。

<meta name="csrf" content="<%= Plug.CSRFProtection.get_csrf_token() %>" />

它在服务器上发送,以及我在Chrome中看到的每个ajax请求。但我的服务器总是返回:

"403: invalid CSRF (Cross Site Request Forgery) token, make sure all requests include a valid '_csrf_token' param or 'x-csrf-token' header"

为什么呢?如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

我认为名称应该是“csrf-token”而不仅仅是“csrf”。这就是我在app.html.eex中使用的内容(它来自ex_turbolinks库自述文件。

<meta name="csrf-token" content="<%= get_csrf_token() %>">
<meta name="csrf-param" content="_csrf_token">

但是,为了在视图中仅使用get_csrf_token / 0,您必须将get_csrf_token: 0添加到my_app_web.ex中view函数中Phoenix.Controller的导入列表中。例如:

lib/my_app_web.ex

def view do
  quote do
  ...
  # Import convenience functions from controllers
  import Phoenix.Controller, only: [get_flash: 2, view_module: 1, 
  get_csrf_token: 0]
  ...
  end
end

答案 1 :(得分:0)

name="csrf-token" id="csrf-token" value="<%= Plug.CSRFProtection.get_csrf_token() %>" 试试这个 。这对我有用

var xhr = new XMLHttpRequest();
 var csrf_token = document.getElementById('csrf-token').value;
 xhr.open('POST', '/api/vote');
 xhr.setRequestHeader('Content-Type', 'application/json');
 xhr.setRequestHeader("X-CSRF-Token", csrf_token);

这是我的ajax请求