Created
October 17, 2014 06:41
-
-
Save jfornoff/4637069c398dc2f5b881 to your computer and use it in GitHub Desktop.
Angular.js Authentication Error Handling with HTTP Interceptor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var app = angular.module('someApp', [ | |
'ngCookies', | |
'ngResource', | |
'ngSanitize', | |
'ui.bootstrap', | |
'ui.router' | |
]); | |
// (Routes not here for brevity) | |
app.config(['$httpProvider', function($httpProvider) { | |
$httpProvider.defaults.useXDomain = true; | |
$httpProvider.defaults.withCredentials = true; | |
delete $httpProvider.defaults.headers.common['X-Requested-With']; | |
$httpProvider.interceptors.push('notLoggedInInterceptor'); | |
} | |
]); | |
// register the interceptor as a service | |
app.factory('notLoggedInInterceptor', function($q, $location, $rootScope) { | |
return { | |
// optional method | |
'request': function(config) { | |
// do something on success | |
return config || $q.when(config); | |
}, | |
// optional method | |
'requestError': function(rejection) { | |
// do something on error | |
return $q.reject(rejection); | |
}, | |
// optional method | |
'response': function(response) { | |
// do something on success | |
return response || $q.when(response); | |
}, | |
// optional method | |
'responseError': function(rejection) { | |
// do something on error | |
console.log('Response Error caught.'); | |
if(rejection.status === 401){ | |
if($location.path() == '/login' && rejection.config.method == "POST") { | |
toastr.error('Please try again','Login failed!') | |
}; | |
$rootScope.user = {}; | |
$rootScope.redirectTo('/login'); | |
if($location.path() != '/' && $location.path() != '/login'){ | |
var deferred = $q.defer(); | |
var req = { | |
config: rejection.config, | |
deferred: deferred, | |
location: $location.path() | |
}; | |
$rootScope.requestsUnauthenticated = req; | |
return deferred.promise; | |
} | |
} | |
else if(rejection.status === 403){ | |
$rootScope.redirectTo('/dashboard'); | |
return $q.reject(rejection); | |
}else{ | |
return $q.reject(rejection); | |
} | |
} | |
}; | |
}); | |
app.config(function ($locationProvider) { | |
$locationProvider.html5Mode(false); //change this to switch between hashbang mode and html5 mode | |
}); | |
app.run(function($rootScope, $http, $location, $timeout) { | |
// Handling of 401 | |
$rootScope.requestsUnauthenticated = null; | |
// I have not the slightest clue why Angular is hiding $location while routing sometimes. | |
$rootScope.redirectTo = function(path) { | |
$timeout(function() { | |
$rootScope.$apply(function() { | |
$location.path(path); | |
}); | |
}) | |
}; | |
/** | |
* On ‚event:loginConfirmed’, resend all the 401 requests. | |
* Which have been intercepted by unauthenticated-filter | |
*/ | |
$rootScope.$on('event:loginConfirmed', function() { | |
console.log('LoginConfirmed invoked.'); | |
var request = $rootScope.requestsUnauthenticated; | |
if(request){ | |
retry(request); | |
}else{ | |
// redirect to dashboard | |
$rootScope.redirectTo('/dashboard'); | |
} | |
$rootScope.requestsUnauthenticated = null; | |
function retry(req) { | |
$http(req.config).then(function(response) { | |
req.deferred.resolve(response); | |
$rootScope.redirectTo(req.location); | |
}); | |
} | |
}); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
app.factory('Authentication', function($http, $rootScope, $location, $timeout){ | |
var Auth = {}; | |
Auth.unsetUser = function() { | |
$rootScope.user = {}; | |
}; | |
Auth.setUser = function(data) { | |
$rootScope.user = data; | |
// Determine if user is admin | |
$rootScope.user.isAdmin = false; | |
for (var i = $rootScope.user.roles.length - 1; i >= 0; i--) { | |
if($rootScope.user.roles[i].name == 'Administrator'){ | |
$rootScope.user.isAdmin = true; | |
break; | |
} | |
}; | |
} | |
Auth.load = function(){ | |
$http.get(API_SERVER_HOST+'/login') | |
.success(function(data, status) { | |
console.log('Call completed with status '+status+' and data '+JSON.stringify(data)); | |
if(status == 200) | |
{ | |
Auth.setUser(data); | |
} | |
else | |
{ | |
console.log('Auth.load status: '+status); | |
Auth.unsetUser(); | |
} | |
}) | |
.error(function(data, status) { | |
Auth.unsetUser(); | |
console.log('Call completed with status '+status+' and data '+JSON.stringify(data)); | |
}); | |
}; | |
Auth.login = function(credentials){ | |
$http.post(API_SERVER_HOST+'/login', credentials).success(function(data, status) { | |
if(status == 200){ | |
Auth.load(); | |
console.log('Already logged in! User: '+JSON.stringify($rootScope.user)); | |
}else{ | |
console.log('Call completed with status '+status+' and data '+JSON.stringify(data)); | |
Auth.setUser(data); | |
$rootScope.$broadcast('event:loginConfirmed'); | |
} | |
}) | |
.error(function(data, status) { | |
Auth.unsetUser(); | |
console.log('Call completed with status '+status+' and data '+JSON.stringify(data)); | |
});; | |
}; | |
Auth.logout = function(){ | |
$http.get(API_SERVER_HOST+'/logout').success(function(data,status) { | |
Auth.unsetUser(); | |
console.log('User logged out!'); | |
$timeout(function() { | |
$rootScope.redirectTo('/login'); | |
}); | |
}).error(function(data, status) { | |
Auth.unsetUser(); | |
console.log('Logout failed!'); | |
}); | |
}; | |
return Auth; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment