Phoenix CSRF令牌不匹配

时间:2016-10-04 23:10:31

标签: elixir csrf phoenix-framework

试图让ajax在凤凰城工作。我通过执行以下操作获得了csrf令牌,所以我拥有它:

<input type="hidden" id="_csrf_token"  name="_csrf_token" value="<%= get_csrf_token() %>">

然后像这样使用它:

$.ajax({
  type: "POST",
  url: "<%= lesson_path @conn, :create %>",
  beforeSend: function(xhr)
  {
    token = $('#_csrf_token').val();
    xhr.setRequestHeader('_csrf_token', token );
  },
  data: data,
  success: function(data, textStatus, jqXHR) {
    alert(textStatus);
  }
});

问题是我获得的令牌不是正确的令牌。看看谷歌浏览器检查员,我得到403请求说有一个无效的csrf令牌。有效的会话令牌总是与它给我的令牌不同。得到类似IiJndz5FeV9MMhIKMzggUTtmHUALAAAAkJ/6Yr/k4BxdiKmiaMUqsw==之类的东西,它通常需要像hHAg7V4xpjnZsM8Z+H1xw==

这样的东西

我知道为什么我会获得与其想要的不同的令牌?

我也尝试了以下内容:

Plug.Conn.get_session(conn, :csrf_token)
Map.get(conn.req_cookies, "_csrf_token")

两者都不会导致任何返回。

2 个答案:

答案 0 :(得分:1)

  

请求可以通过带有密钥“_csrf_token”的参数或名称为“x-csrf-token”的标头发送。

尝试使用键设置标题:

x-csrf-token

答案 1 :(得分:0)

感谢。花了我几个小时。我最终得到了:

<div class="form-group">
  <form id="number" name="number" method="post">
    <meta name="csrf" content="<%= Plug.CSRFProtection.get_csrf_token() %>">
    <input id="_csrf_token" name="_csrf_token"
       type="hidden" value="<%= Plug.CSRFProtection.get_csrf_token() %>">
    <%= text_input :blocks, :num, value: "" %>
    <%= submit "Submit", id: "submit", class: "btn btn-primary" %>
  </form>
</div>

<script>
  var csrf = document.querySelector("meta[name=csrf]").content;

  $.ajax({
    url: "/posts",
    type: "post",
    data: {
      post: { title: post } })
    },
    headers: {
        "X-CSRF-TOKEN": csrf
    },
    dataType: "json",
    success: function (data) {
      console.log(data);
    }
  });
</script>

我不知道X-CRSF-TOKEN标头或_csrf_token参数是否必要,或两者兼而有之,所以我会试着通过反复试验找出。