AngularJS中的授权标题无效 [英] Authorization header in AngularJS not working

查看:134
本文介绍了AngularJS中的授权标题无效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为我的API使用Django REST令牌验证。



我发布了我的凭据来获取令牌端点。但是,当我尝试以正确的方式设置头部时,它会继续响应http 401错误。我尝试使用 curl -X GET http://127.0.0.1:8000/events/ -H'授权:令牌4d92d36768ca5d555b59cf68899eceab39c23704',并且工作!这是我的代码:

  app.controller('HomeController',['$ scope','$ http',function $ scope,$ http){
$ scope.username ='';
$ scope.password ='';
$ scope.submitLogin = function(){
var credentials = {
username:$ scope.username,
password:$ scope.password,
};

var req = $ http.post('http: /127.0.0.1:8000/api-token-auth/',credentials);
req.success(function(data,status,headers,config){
$ scope.token = data.token;
var str1 ='Token';
$ scope.tokenheader = str1.concat($ scope.token);
$ http.defaults.headers.common.Authorization = $ scope.tokenheader;
});
req.error(function(data,status,headers,config){
alert(failure message:+ JSON.stringify({data:data}));
});
};
$ scope.getEvents = function(){
var req = {
method:'GET',
url:'http://127.0.0.1:8000/events/',
}
$ http(req).then(
function(){
console.log('succes')
},
function(){
console .log('fail')
});
};
}]);

Chrome开发工具中的错误消息:


  XMLHttpRequest无法加载http://127.0.0.1:8000/events/。 
预检的响应具有无效的HTTP状态代码401




编辑:我刚刚发现错误在于事实上我没有在我的API上安装CORS。我正在Chrome中使用CORS插件,用于我的api的认证部分,但不适用于我的事件url!

解决方案

您检查该令牌是否实际添加到您的请求?



您可以这样做,例如使用Chrome开发人员工具。



我个人喜欢使用$ httpprovider.interceptor,如下所述:



angularjs $ httpProvider拦截器文档



这样可以确保令牌是总是出现在任何一个电话。



如果您正在访问多个API,则应考虑添加以下内容:

 code> $ httpProvider.interceptors.push(['$ q','$ location','$ log','loginService','restHelperService',
函数($ q,$ location,$ log ,loginService,restHelperService){
return {
request:function(config){
//检查请求是否附带一个url
if(config.url){
//检查调用是否为REST api,如果是,则添加令牌
if(restHelperService.isRestCall(config.url)){
//添加auth标头或恢复登录
if(loginService.userIsLoggedIn()){
config.headers = config.headers || {};
config.headers .Authorization ='Token'+ loginService.getToken()。token;
} else {
$ location.path('/ login');
}
}
}
return config;
},
responseError:function(response){
if(response.status === 401 || response.status === 403){
//清除auth令牌如果REST调用失败,当前令牌
if(response.config&& response.config.url&& restHelperService.isRestCall(response.config.url)){
$ log。调试(由于凭据不正确而重新启动凭证而导致restCall失败);
loginService.resetCredentials();
$ location.path('/ login');
}
}
return $ q.reject(response);
}
};
}]);
}])

这样可以避免在开始向API添加令牌时出现问题不要指望的电话。此外,代码确保如果凭据无效,用户将被自动重定向到登录页面。



这个例子,我正在使用两个额外的服务。一个用于管理令牌的loginService和一个用于管理REST框架的URL的restHelperService。



我建议做同样的事情,否则很难从控制器外部访问凭据。


I am using the Django REST token authentication for my API.

I posted my credentials to obtain token endpoint. However when I try to set the header in a correct way it keeps responding with a http 401 error. I tried it using curl -X GET http://127.0.0.1:8000/events/ -H 'Authorization: Token 4d92d36768ca5d555b59cf68899eceab39c23704 ' and that does work! This is my code:

app.controller('HomeController', ['$scope','$http', function($scope,$http) {
    $scope.username = '';
    $scope.password = '';
    $scope.submitLogin = function () {
        var credentials = {
            username : $scope.username,
            password : $scope.password,
        };

        var req = $http.post('http://127.0.0.1:8000/api-token-auth/', credentials);
        req.success(function(data, status, headers, config) {
            $scope.token = data.token;
            var str1 = 'Token ';
            $scope.tokenheader = str1.concat($scope.token);
            $http.defaults.headers.common.Authorization = $scope.tokenheader;
        });
        req.error(function(data, status, headers, config) {
            alert( "failure message: " + JSON.stringify({data: data}));
        });
    };
    $scope.getEvents = function () {
        var req = {
            method: 'GET',
            url: 'http://127.0.0.1:8000/events/',
        }
        $http(req).then( 
           function() {
                       console.log('succes')
           }, 
           function(){
                       console.log('fail') 
        });
    };
}]);

And the error message in chrome dev tools:

XMLHttpRequest cannot load http://127.0.0.1:8000/events/. 
Response for preflight has invalid HTTP status code 401

How do I get rid of this 401 error?

Edit: I just found out the fault lies in the fact that I did not have CORS installed on my API. I was using a CORS plugin in chrome that worked for the authentication part of my api but not for my events url!

解决方案

Did you check that the token is actually added to your request?

You can do this for example using the Chrome developers tools.

Personally I prefer to use the $httpprovider.interceptor as described in:

angularjs $httpProvider interceptor documentation

This ensures that the tokens are always present on any call.

If you are accessing more than one API, you should consider adding something like:

           $httpProvider.interceptors.push(['$q', '$location', '$log', 'loginService', 'restHelperService',
            function ($q, $location, $log, loginService, restHelperService) {
                return {
                    request: function (config) {
                        // check if the request comes with an url
                        if (config.url) {
                            // check that the call is to the REST api, if yes add token
                            if (restHelperService.isRestCall(config.url)) {
                                // add auth header or revert to login
                                if (loginService.userIsLoggedIn()) {
                                    config.headers = config.headers || {};
                                    config.headers.Authorization = 'Token ' + loginService.getToken().token;
                                } else {
                                    $location.path('/login');
                                }
                            }
                        }
                        return config;
                    },
                    responseError: function (response) {
                        if (response.status === 401 || response.status === 403) {
                            // clear auth token if the REST call failed with the current token
                            if (response.config && response.config.url && restHelperService.isRestCall(response.config.url)) {
                                $log.debug(" restCall failed due to bad credentials, resetting credentials");
                                loginService.resetCredentials();
                                $location.path('/login');
                            }
                        }
                        return $q.reject(response);
                    }
                };
            }]);
    }])

This avoid issues that will arise when you start adding the token to API calls that don't expect them. Also the code ensures that a user will be automatically redirected to the login page if the credentials are not valid.

The example, I'm using two additional services. A loginService that manages the tokens and a restHelperService that manages the urls of the REST framework.

I would recommend doing the same as else it will be hard to access the credentials from outside your controller.

这篇关于AngularJS中的授权标题无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆