首先,我只想说我已阅读了与此主题相关的所有其他主题,但没有任何运气。以下是该问题的细分:
目标
为了满足目标1,我创建了一个Ember初始化程序,它在应用程序首次启动时运行(如果有更好的位置,我完全愿意接受建议)。为了满足目标2,我从Sails中检索CSRF令牌,然后尝试使用Ember.$.ajaxSetup()
来确保CSRF令牌作为标头(X-CSRF-Token
)或参数(_csrf
)传递。我还确保我使用withCredentials
选项来确保设置cookie。这是代码:
// 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
};
所有这些看起来都有用,因为我在Chrome开发工具中可以看到正在检索CSRF令牌,当我发出AJAX请求时,我看到附加到POST数据的数据或添加为标题(尝试了两个选项) )。这是我正在运行的代码以及所有相关的标题:
Ember.$.post(config.APP.API_URL + '/auth/register', {
'email': _this.get('email'),
'password': _this.get('password')
}).then(function(response) {
console.log('It worked!');
});
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
_csrf:yP7GDiU2-YGmLBfBvQtMPT3-hRpnfK0x-AfA
email:test@test.com
password:q1w2e3r4
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
从响应标头中可以看出,我最终收到来自Sails的403 Forbidden - CSRF Mismatch
。现在,这里有点奇怪:首先,我能够与Postman一起运行。我检索一个令牌,然后将该令牌与数据一起发布到/auth/register
网址,并按预期工作。
我也尝试删除初始化程序并运行以下代码:
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!');
});
});
这有效。然而,在这一点上,我对这个问题究竟是什么感到有些失落。感谢我能得到的任何帮助。
提前致谢! 詹姆斯
答案 0 :(得分:2)
@ jdixon04,您可以在通过POST发送之前尝试对CSRF令牌进行URL编码吗?如果令牌从原始版本更改,则会发生令牌不匹配。
我在Github中发现了这个问题:https://github.com/balderdashy/sails/issues/2266。
我希望这能解决你的问题。试一试,让我知道它是否有效。感谢。
答案 1 :(得分:2)
@ jdixon04,来自your post on my github issue。实际上,在向服务器发出的每个请求中,CSRF令牌是否会发生变化?然后,当前端加载无法处理此问题时,您可以修复令牌,您可能必须在每个请求之前获取令牌并使用ajaxPrefilter
将其传递给请求。
这实际上与ember-data-sails有关吗?在我看来,你在这里做纯粹的ajax!如果你查看我的配置,你会发现纯粹的ajax调用(也用于身份验证)免于csrf,因为我无法按照我的意愿使用它:\。
答案 2 :(得分:0)
像这样添加x-csrf-token标头:
Ember.$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': result._csrf
},
xhrFields: { withCredentials: true }
});