我在应用程序范围内处理401错误时遇到了一些麻烦。
其他一些没有真正帮助我的帖子: Angularjs - handling 401's for entire app 401 unauthorized error handling in AngularJS
我必须发送一个身份验证令牌,如果它是在每个请求上定义的,这就是为什么我需要拦截器中的请求部分。
我目前的方法如下:
module.factory('authInterceptor', function ($rootScope, $q, $window, $location) {
return {
request: function (config) {
config.headers = config.headers || {};
if ($window.sessionStorage.token) {
config.headers.Authorization = 'Bearer ' + $window.sessionStorage.token;
}
else{
console.log("authInterceptor: No Token to send")
}
return config;
},
response: function (response) {
if (response.status == 401) {
console.log("No Logged In");
$location.path('/login');
}
return response || $q.when(response);
},
responseError: function(rejection){
var defer = $q.defer();
if(rejection.status == 401){
console.log("401 Rejection");
console.dir(rejection);
}
defer.reject(rejection);
return defer.promise;
}
};
});
就我的调试而言,如果401在请求之后发生,它将在repsonse函数中处理。这本身就是对原始来电者的承诺。
如果我注释掉$ q.when(响应)并且只返回repsonse则没有变化。
甚至在原始调用者获得.error
之前就会调用响应任何想法的Thx。希望我不要远离解决方案。
答案 0 :(得分:2)
我遇到了同样的问题,在我的情况下问题是我在响应中添加了CORS标头作为后置过滤器,这意味着在发出401时它们没有被发送。
不确定您使用的是哪种类型的服务器,但这是适用于我的rails版本(将其更改为 before_filter :
before_filter :allow_cors
def allow_cors
headers['Access-Control-Allow-Origin'] = '*'
headers['Access-Control-Allow-Methods'] = 'POST, PUT, GET, OPTIONS'
headers['Access-Control-Allow-Headers'] = 'Accept, Cache-Control, Referer, User-Agent, Origin, X-Requested-With, X-Prototype-Version, Content-Type, accept, autho
headers['Access-Control-Allow-Credentials'] = 'true'
headers['Access-Control-Request-Method'] = '*'
headers['Access-Control-Max-Age'] = '1728000'
end
(显然这些是非常宽松的设置,所以请在生产中使用之前调整它们)
他们通过CURL在本地测试请求,我设法找到了这个,所以这可能对你有所帮助:
curl -H "Origin: http://example.com" --verbose http://localhost:3000/
通过这种方式,即使请求未获得授权,您也可以查看是否正确返回了标题。
答案 1 :(得分:0)
你的方法很好。
我认为你不需要“响应”拦截器,只需“请求”注入令牌和“responseError”来处理401响应错误:
return {
'responseError': function(response) {
if (response && response.status === 401) {
//DO WHAT YOU WANT HERE
console.log("There was a 401 error");
}
return $q.reject(response);
},
'request': function(config) {
config.headers = config.headers || {};
// ADD YOUR HEADER HERE
return config || $q.when(config);
}
};
答案 2 :(得分:0)
@frankmt非常感谢!没有足够的代表来支持或评论您的解决方案,无论如何,这正是我错过的。使用Express和CORS,它将是......
// THE CORS BLOCK HAS TO GO BEFORE THE JWT BLOCK
app.options('*', cors());
app.use(cors());
//protect routes with JWT - Token based auth
var secret = 'env.SECRET';
var publicPaths = [ '/apply', '/login'];
app.use('/', expressJwt({secret: secret}).unless({path: publicPaths}));
答案 3 :(得分:0)
如果你有堆叠中的Devise;它最有可能失败,因为Warden优先于其他任何事情。标题不会被插入;即使您使用before_action
代替after_action
。