我有以下授权拦截器,当401发生时,它会将用户重定向到我的登录路由:
app.factory('authHttpResponseInterceptor', ['$q', '$location', function ($q, $location) {
return {
response: function (response) {
if (response.status === 401) {
console.log("Response 401");
}
return response || $q.when(response);
},
responseError: function (rejection) {
if (rejection.status === 401 && $location.path() !== '/') {
$location.path('/login').search('returnUrl', $location.path());
}
return $q.reject(rejection);
}
}
}]);
我希望它将用户尝试访问的URL设置为returnURL。不幸的是,如果网址类似于/join?code123&id=456
,则会重定向到/login?code123&id=456&returnUrl=%2Flogin
。正如您所看到的,它将查询字符串保留在查询字符串中,而不是将其包含在returnUrl
中。
然后我想在重定向中使用$location.url()
,如下所示:
$location.path('/login').search('returnUrl', $location.url());
...确实将完整的查询字符串放在returnUrl
中,但查询字符串仍然保留在这样的路径中:/login?code123&id=456&returnUrl=%2Flogin%3Fcode%3D123%26id%3D456
。 AFAIK,要从查询字符串中删除项目,您必须手动清除它们(例如$location.path().search('code', null)
),这是不正确的。
提前致谢。
答案 0 :(得分:0)
我最终以稍微不同的方式解决了这个问题。
我摆脱了returnUrl代码,这样我的拦截器的responseError看起来像这样:
responseError: function (rejection) {
if (rejection.status === 401 && $location.path() !== '/') {
$location.path('/login');
}
return $q.reject(rejection);
}
然后我添加了以下内容:
app.run(['$rootScope', function ($rootScope) {
$rootScope.$on('$locationChangeStart', function (evt, absNewUrl, absOldUrl) {
$rootScope.previousPage = absOldUrl;
});
}]);
然后我处理重定向后登录的代码如下所示:
var login = function (credentials) {
return $http.post('/api/login', credentials).then(function (response) {
var previousUrl = urlParserFilter($rootScope.previousPage);
var path = previousUrl.hash.substr(1);
if (path !== '/login') {
$location.path(path);
}
else {
$location.path('/');
}
});
};
遗憾的是,这仍然无法正确处理查询字符串,但它确实处理重定向,并且我将我的网站中包含查询字符串的唯一区域重新编写为不同的URL结构。我最终使用urlParser库来提供帮助。