AngularJS:使用来自api的csrf标记将异步数据初始化为常量

时间:2014-05-20 11:00:28

标签: angularjs http http-headers csrf

我希望查询API以获取CSRF令牌。然后在所有HTTP请求的标头中设置此标记。

在我将CSRF令牌设置为angularJS应用程序的常量之前,我遇到了一些困难。

app.run(['$http', function($http) {

    var csrf = $http( { method: 'GET', url: 'api/csrf' })
            .success(function(data) {
                console.log("CSRF Success: " + data.token);
                return data.token;
            })
            .error(function(data) {
                console.log("CSRF ERROR: " + data);
            });

        console.log("CSRF TOKEN: " + csrf);
        $http.defaults.headers.common['X-Csrf-Token'] = csrf;
}]);

当我运行我的应用程序时,我在浏览器控制台中获得以下内容:

CSRF TOKEN: [object Object] scripts.js?v=1400582971:32411
GET http://testapp/api/v1/supplier 400 (Bad Request) scripts.js?v=1400582971:17571
CSRF Success: zD7TrQWQWma0eHYtzM8NcgbvitB9XJzTCegjAVMg scripts.js?v=1400582971:32404

这里有几个问题......

  • 首先,CSRF Success之前应输出CSRF TOKEN
  • 其次,CSRF TOKEN: [object Object]应为CSRF TOKEN: zD7TrQWQWma0eHYtzM8NcgbvitB9XJzTCegjAVMg
  • 第三,400(错误请求)的原因是因为get请求中发送的标头是X-Csrf-Token:[object Object]。标题应为X-Csrf-Token:zD7TrQWQWma0eHYtzM8NcgbvitB9XJzTCegjAVMg

我不希望变量csrf成为对象。它需要是一个实际的字符串值。

一旦我有了这个工作,我希望提取出http请求并执行以下操作:

app.factory("CSRF_TOKEN", function($http) {

    var token;

    $http( { method: 'GET', url: 'api/csrf' })
                .success(function(data) {
                    console.log("CSRF Success: " + data.token);
                    token = data.token;
                })
                .error(function(data) {
                    console.log("CSRF ERROR: " + data);
                });
});

app.run(['$http', 'CSRF_TOKEN', function($http, CSRF_TOKEN) {
    $http.defaults.headers.common['X-Csrf-Token'] = CSRF_TOKEN.token;
}]);

我的问题解决方案:

var xhReq = new XMLHttpRequest();
xhReq.open("GET", "//" + window.location.hostname + "/api/csrf", false);
xhReq.send(null);

app.constant("CSRF_TOKEN", xhReq.responseText);

app.run(['$http', 'CSRF_TOKEN', function($http, CSRF_TOKEN) {

    console.log("Injected CSRF: " + CSRF_TOKEN);

    $http.defaults.headers.common['X-Csrf-Token'] = CSRF_TOKEN;
}]);

1 个答案:

答案 0 :(得分:0)

您的原始解决方案无法正常工作,因为您希望$http.get返回您的令牌,但实际上此方法会返回promise。实际数据(您的令牌)通过success函数异步返回。

您的原始代码可能看起来像这样:

$http({ method: 'GET', url: 'api/csrf' })
        .success(function(response) {
            var token = response.data.token;
            console.log("CSRF Success: " + token);
            $http.defaults.headers.common['X-Csrf-Token'] = token;
            //carry on with processing
        })
        .error(function(response) {
            console.log("CSRF ERROR: " + response.status);
});