title: Can't verify CSRF token authenticity Rails 4 Ajax even when header is set
body: <p>I'm really having trouble with this, and in this instance, I neither want to skip the <code>verify_authenticity_token</code> filter, nor change to <code>protect_from_forgery with: :null_session</code>. </p>
  
  <p>In my request method, I am setting a header with the csrf token as follows:</p>
  
  <pre><code>var token = document.querySelector("meta[name='csrf-token']").content;
  xhr.setRequestHeader("X-CSRF-Token", token);
  </code></pre>
  
  <p>And by inserting a breakpoint in my controller like so:</p>
  
  <pre><code>def verify_authenticity_token
    binding.pry
    super
  end
  </code></pre>
  
  <p>I have verified that the header is set:</p>
  
  <pre><code>[1] pry(#&lt;MyController&gt;)&gt; request.headers
  =&gt; #&lt;ActionDispatch::Http::Headers:0x007fb227cbf490
   @env=
    {"CONTENT_LENGTH"=&gt;"202",
     .
     .
     .
     # omitted headers
     .
     .
     .
     "HTTP_X_CSRF_TOKEN"=&gt;"the-correct-token-from-meta-tag",
     .
     .
     .
    }
  </code></pre>
  
  <p>I have also tried passing the token as a param with the key <code>authenticity_token</code> (as is done with Rails forms), and set the <code>X-CSRF-Param</code> tag to match (from <code>meta[name="csrf-param"]</code>).</p>
  
  <p>Yet I am still getting:</p>
  
  <pre><code>Can't verify CSRF token authenticity
  Completed 422 Unprocessable Entity in 14638ms
  
  ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken
  </code></pre>
  
  <p>Anyone seen this before? Any thoughts on what might cause this? </p>
  
  <p>Thanks in advance!</p>
  
  <p>EDIT:</p>
  
  <p>Following discussion in the comments of marflar's answer, it looks like the token has expired when the request is made (tested by comparing to <code>form_authenticity_token</code>). This is confusing me further, as the token set in <code>&lt;%= csrf_meta_tags %&gt;</code> is expired when the next request comes in. Any thoughts?</p>
  
  <p>EDIT2: Following marflar's advice below, I added the following <code>after_filter</code> to my app controller:</p>
  
  <pre><code>def set_csrf_headers
    response.headers['X-CSRF-Param'] = request_forgery_protection_token.to_s
    response.headers['X-CSRF-Token'] = form_authenticity_token
  end
  </code></pre>
  
  <p>And I updated <code>xhr.onload</code> in my request method as follows:</p>
  
  <pre><code>namespace.request = = function (type, url, opts, callback) {
  
  // code omitted
  
    xhr.onload = function () {
      setCSRFHeaders(xhr);
      var res = {data: JSON.parse(xhr.response), status: xhr.status};
      return callback.call(xhr, null, res);
    };
  
  // code omitted
  
  }
  
  function setCSRFHeaders ( xhr ) {
    var csrf_param = xhr.getResponseHeader('X-CSRF-Param');
    var csrf_token = xhr.getResponseHeader('X-CSRF-Token');
  
    if (csrf_param) {
      document.querySelector("meta[name='csrf-param']").content = csrf_param;
    }
    if (csrf_token) {
      document.querySelector("meta[name='csrf-token']").content = csrf_token;
    }
  }
  </code></pre>
  
  <p>I verified that the response headers, and then the meta tags are getting reset properly, however, by the time the next request comes in, this new token is expired again. Thoughts?</p>