授权头在AngularJS不工作 [英] Authorization header in AngularJS not working

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

问题描述

我使用的是Django的REST令牌认证为我的API。

我贴我的凭据来获得令牌端点。然而,当我尝试设置页眉以正确的方式它使一个HTTP 401错误响应。我试着用它卷曲-X GET http://127.0.0.1:8000/events/ -H'授权:令牌4d92d36768ca5d555b59cf68899eceab39c23704 并没有工作!这是我的code:

  app.controller(HomeController中',['$范围,$ HTTP',函数($范围,$ HTTP){
    $ scope.username ='';
    $ scope.password ='​​';
    $ scope.submitLogin =功能(){
        VAR凭证= {
            用户名:$ scope.username,
            密码:$ scope.password,
        };        VAR REQ = $ http.post('http://127.0.0.1:8000/api-token-auth/,证书);
        req.success(功能(数据,状态,头,配置){
            $ scope.token = data.token;
            VAR STR1 ='令牌';
            $ scope.tokenheader = str1.concat($ scope.token);
            $ http.defaults.headers.common.Authorization = $ scope.tokenheader;
        });
        req.error(功能(数据,状态,头,配置){
            警报(失败消息:+ JSON.stringify({数据:数据}));
        });
    };
    $ scope.getEvents =功能(){
        VAR REQ = {
            方法:GET,
            网址:'http://127.0.0.1:8000/events/',
        }
        $ HTTP(REQ)。然后(
           功能(){
                       的console.log('更迭')
           },
           功能(){
                       的console.log('失败')
        });
    };
}]);

和在Chrome开发工具的错误消息:


  XMLHtt prequest无法加载http://127.0.0.1:8000/events/。
为preflight响应具有无效的HTTP状态code 401


如何摆脱这个401错误的?

编辑:我刚刚发现故障出的事实,我没有安装在我的API CORS。我是用在Chrome中,CORS插件,为我的API认证的一部分,但不是我的活动URL的工作!


解决方案

你是否检查该令牌实际上是添加到您的要求吗?

您可以使用Chrome的开发人员工具,例如做到这一点。

我个人preFER使用$ httpprovider.interceptor中所述:

<一个href=\"http://stackoverflow.com/questions/26171986/angularjs-httpprovider-interceptor-documentation\">angularjs $ httpProvider拦截文档

这确保令牌总是在任何调用present。

如果您正在访问多个API,你应该考虑增加类似:

  $ httpProvider.interceptors.push(['$ Q','$的位置,$日志','login服务','restHelperService',
            功能($ Q $的位置,$日志,login服务,restHelperService){
                返回{
                    要求:功能(配置){
                        //检查请求附带一个网址
                        如果(config.url){
                            //检查调用的REST API,如果是添加令牌
                            如果(restHelperService.isRestCall(config.url)){
                                //添加AUTH头或恢复登录
                                如果(loginService.userIsLoggedIn()){
                                    config.headers = config.headers || {};
                                    config.headers.Authorization ='令牌'+ loginService.getToken()标记。
                                }其他{
                                    $ location.path('/登录');
                                }
                            }
                        }
                        返回配置;
                    },
                    responseError:功能(响应){
                        如果(response.status === 401 || response.status === 403){
                            //明确的身份验证令牌如果REST调用失败,当前令牌
                            如果(response.config&放大器;&放大器; response.config.url&放大器;&放大器; restHelperService.isRestCall(response.config.url)){
                                $ log.debug(restCall失败,原因是糟糕的凭据,凭据复位);
                                loginService.resetCredentials();
                                $ location.path('/登录');
                            }
                        }
                        返回$ q.reject(响应);
                    }
                };
            }]);
    }])

这是当你开始加入令牌不指望他们的API调用会出现避免出现问题。另外,code可确保用户如果凭据无效被自动重定向到登录页面。

这个例子中,我使用两个额外的服务。管理该令牌的login服务和管理的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天全站免登陆