【问题标题】:Authorization header in AngularJS not workingAngularJS中的授权标头不起作用
【发布时间】:2016-02-11 05:01:16
【问题描述】:

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

我发布了我的凭据以获取令牌端点。但是,当我尝试以正确的方式设置标头时,它会一直响应 http 401 错误。我使用curl -X GET http://127.0.0.1:8000/events/ -H 'Authorization: Token 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 cannot load http://127.0.0.1:8000/events/. 
Response for preflight has invalid HTTP status code 401

如何摆脱这个 401 错误?

编辑:我刚刚发现错误在于我的 API 上没有安装 CORS。我在 chrome 中使用了一个 CORS 插件,该插件适用于我的 api 的身份验证部分,但不适用于我的事件 url!

【问题讨论】:

  • 真的在 submitLogin 上调用了 success 回调吗?不推荐使用旧的 promise 方法 successerror
  • 是的,他们正在工作。我得到了令牌,我的 api 的 http 响应代码是 200

标签: angularjs django http-headers django-rest-framework token


【解决方案1】:

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

例如,您可以使用 Chrome 开发人员工具执行此操作。

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

angularjs $httpProvider interceptor documentation

这可确保令牌始终存在于任何呼叫中。

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

           $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);
                    }
                };
            }]);
    }])

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

例如,我正在使用两个附加服务。一个管理令牌的 loginService 和一个管理 REST 框架 url 的 restHelperService。

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

【讨论】:

【解决方案2】:

需要在header中添加Token:

get($http, "/some_url", {headers: {"Authorization": "Token " + $your_token}}
    ....
    ....
);

响应代码 401 表示未经授权。如果您使用基于令牌的身份验证,那么在失败的情况下,它将是 403,禁止。 所以我的猜测是用户名/密码在弄乱它。在您的 curl 示例中,您没有使用它们。

【讨论】:

  • 我已经这样做了:var str1 = 'Token '; $scope.tokenheader = str1.concat($scope.token);
  • @icam0,但是你为什么要使用用户名和密码呢?我更新了我的答案。
  • 那是因为在我的 html 中有 2 个按钮。一个连接到 submitlogin() 函数,另一个连接到 getEvent() 函数。我首先使用另一个 curl 命令请求令牌:curl -X POST http://127.0.0.1:8000/auth/login/ --data ‘username=icam0&password=password123’
猜你喜欢
  • 2013-09-24
  • 2018-07-24
  • 1970-01-01
  • 2018-07-07
  • 2023-04-09
  • 2015-12-02
  • 1970-01-01
  • 2015-12-19
  • 2015-08-18
相关资源
最近更新 更多