Handle redirects in angularjs $http
I think there is a better way than the http interceptor for login redirection because it parses the request response and if another page has the string requested, an error will occur.
I suggest wrapping $http methods in your service and check if the user is logged before making the request:
app.service('httpWrapper', ['$http','requestLogin',function($http,requestLogin){
var httpWrapper = {};
// You can add methods for put, post
httpWrapper.get = function(url){
// Before making the request, check with a request if the user is logged
$http.get(urlLogged).success(function (auth) {
if(!auth.logged){
// Show login widget
requestLogin.show();
}
}).error(function(){
});
return $http.get(url);
}
return httpWrapper;
}]);
Then uses httpWrapper in place of $http in your other services:
app.service('otherService', ['httpWrapper',function(httpWrapper){
httpWrapper.get(url);
}]);
Here the service for requestLogin:
app.service('requestLogin', ['$rootScope',function($rootScope){
var requestLogin = {};
$rootScope.showlogin = false;
requestLogin.show = function(){
$rootScope.showlogin = true;
}
requestLogin.hide = function(){
$rootScope.showlogin = false;
}
return requestLogin;
}]);
And then, in your view:
<div ng-show="showlogin == true">
Please log-in...
</div>
I ran into this problem as well, trying to find a nice way of implementing that a user be prompted to change his password, when logging in for the first time.
The way I solved this problem is by letting the server return a (unofficial) 210 status code with a location header, containing the information needed for the UI-Router's state provider. In the controller at the front I have added:
if (data.status == 210) {
var location = data.headers().location;
$state.go(location);
} else {
$state.go("user", {name: data.data.fullName, userId: data.data.userId});
}
Please note that this is specific to my project.
Goal: Catch 302 status code and redirect the page (to login in my case).
Result: In firebug, I could see that the response code is 302 but then I found out that angularjs returns 200 by simply printing the value of status (response.status). So at first you'd thought that you're hopeless. But in my case, what I did was get the data (response.data), look for the string that could be only found in my login page. Then that's it. problem solved :D
The idea was taken here.
Here's the code
app.factory('redirectInterceptor', function($q,$location,$window){
return {
'response':function(response){
if (typeof response.data === 'string' && response.data.indexOf("My Login Page")>-1) {
console.log("LOGIN!!");
console.log(response.data);
$window.location.href = "/login.html";
return $q.reject(response);
}else{
return response;
}
}
}
});
app.config(['$httpProvider',function($httpProvider) {
$httpProvider.interceptors.push('redirectInterceptor');
}]);