Firstly, I just wanted to say that I read all the other topics related to this topic, but no luck. Here's a breakdown of the problem:
purpose
- Get CSRF Token from Sails on Ember Application Launch
- Embed this CSRF token in every AJAX request initiated with the Ember app
To meet goal 1, I created the Ember Initializer, which starts when the application first loads (if there is a better place for this, I am completely open to suggestions). To meet goal 2, I extract the CSRF token from Sails and then try to use Ember.$.ajaxSetup() to ensure that the CSRF token is passed either as a header ( X-CSRF-Token ) or as a parameter ( _csrf ). I also guarantee that I use the withCredentials parameter to make sure the cookie is set. Here is the code:
// initializers/csrf.js import Ember from 'ember'; import config from '../config/environment'; export function initialize() { Ember.$.get(config.APP.API_URL + '/csrfToken').then(function(result) { Ember.$.ajaxSetup({ data: { '_csrf': result._csrf }, xhrFields: { withCredentials: true } }); }, function(error) { console.log(error); }); } export default { name: 'csrf', initialize: initialize };
All this works the way I see in Chrome dev tools that extract the CSRF token, and when I make an AJAX request, I see that the data is added to the POST data or added as a header (both options). Here's the code I'm running and all the related headers:
Ember.$.post(config.APP.API_URL + '/auth/register', { 'email': _this.get('email'), 'password': _this.get('password') }).then(function(response) { console.log('It worked!'); });
Request header
POST /auth/register HTTP/1.1 Host: localhost:1337 Connection: keep-alive Content-Length: 82 Accept: */* Origin: http://localhost:4200 CSP: active User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36 Content-Type: application/x-www-form-urlencoded; charset=UTF-8 DNT: 1 Referer: http://localhost:4200/signup Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.8 Cookie: sails.sid=s%3AbrABhErTY3-ytTWOKFJ2KBj7DCAzaLDc.apD60Sd%2BW85GSbTfJ7E3B2PrUwnhOsW6GlNpZTu9jFg
Form data
_csrf:yP7GDiU2-YGmLBfBvQtMPT3-hRpnfK0x-AfA email: test@test.com password:q1w2e3r4
Answer Headers
HTTP/1.1 403 Forbidden Vary: X-HTTP-Method-Override Access-Control-Allow-Origin: http://localhost:4200 Access-Control-Allow-Credentials: true Content-Type: text/html; charset=utf-8 Content-Length: 13 Date: Thu, 09 Jul 2015 08:11:34 GMT Connection: keep-alive
As seen from the Response headers, I get 403 Forbidden - CSRF Mismatch from Sails. Now, here, where it gets a little weird: first, I can run it just fine with Postman. I extract the token and then send that token along with the data to the /auth/register url and it works as expected.
I also tried removing the initializer and running the following code:
Ember.$.ajaxSetup({ xhrFields: { withCredentials: true } }); Ember.$.get(config.APP.API_URL + '/csrfToken').then(function(result) { Ember.$.post(config.APP.API_URL + '/auth/register', { 'email': _this.get('email'), 'password': _this.get('password'), '_csrf': result._csrf }).then(function(response) { console.log('It worked!'); }); });
It works. However, at the moment I am losing a little, which is actually a problem. Appreciate any help I can get.
Thanks in advance! James