AngularJS 中的授权 header 无效
Authorization header in AngularJS not working
我正在为我的 API 使用 Django REST 令牌身份验证。
我发布了我的凭据以获取令牌端点。但是,当我尝试以正确的方式设置 header 时,它会一直响应 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!
您需要添加Token到headers:
get($http, "/some_url", {headers: {"Authorization": "Token " + $your_token}}
....
....
);
响应码401表示未授权。如果您使用的是基于令牌的身份验证,那么在失败的情况下它将是 403,Forbidden。
所以我的猜测是 username/password 搞砸了。在您的 curl
示例中,您没有使用它们。
您是否检查过令牌是否实际添加到您的请求中?
例如,您可以使用 Chrome 开发人员工具来执行此操作。
就我个人而言,我更喜欢使用 $httpprovider.interceptor,如下所述:
这确保令牌始终出现在任何调用中。
如果您要访问多个 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。
我建议做同样的事情,否则很难从控制器外部访问凭据。
我正在为我的 API 使用 Django REST 令牌身份验证。
我发布了我的凭据以获取令牌端点。但是,当我尝试以正确的方式设置 header 时,它会一直响应 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!
您需要添加Token到headers:
get($http, "/some_url", {headers: {"Authorization": "Token " + $your_token}}
....
....
);
响应码401表示未授权。如果您使用的是基于令牌的身份验证,那么在失败的情况下它将是 403,Forbidden。
所以我的猜测是 username/password 搞砸了。在您的 curl
示例中,您没有使用它们。
您是否检查过令牌是否实际添加到您的请求中?
例如,您可以使用 Chrome 开发人员工具来执行此操作。
就我个人而言,我更喜欢使用 $httpprovider.interceptor,如下所述:
这确保令牌始终出现在任何调用中。
如果您要访问多个 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。
我建议做同样的事情,否则很难从控制器外部访问凭据。