How do I check for login or other status before launching a route in Angular with routeProvider?

早过忘川 提交于 2019-12-04 19:31:33


Let's say I have 4 routes - 2 require the user to be logged in, 2 do not. My app init looks like:


Routes /open1 and /open2 are open to all, while routes /secure1 and /secure2 require the user to be logged in and, if not, take some action, e.g. redirect to login or launch a warning. I can determine the user's state by using my Auth service and calling, e.g., Auth.isLogin(). So the result would be:

  • going to /open1 and /open2 always go to the template and controller declared above
  • if Auth.isLogin() returns true, /secure1 and /secure2 go to the above-declared template and controller
  • if Auth.isLogin() returns false, /secure1 and /secure2 take some other action, e.g. $location.path('/login')

I could put logic in the Secure1 and Secure2 controllers that checks, but that is repetitive and mixes up responsibilities, makes them harder to test, etc.

Is there a way that I can use the $routeProvider to declare, "check this route and this route and if not, redirect"? I was thinking of using resolve somehow, but not quite sure how to work it in (docs on resolve are not very clear, and few helpful examples).


based on the answers below, it appears there are three philosophies for doing this:

  • Using resolve to check logged in and fail the promise, and then catching the $routeChangeError event to redirect
  • Using just $routeChangeStart event to check logged in and redirect
  • Using just resolve to check logged in and redirect

The 2nd option is what the two answerers have suggested.


As in my comments above, there are 3 different paths (plus the ability to use a directive if you want to control it from within html templates). I ended up following

which essentially is as follows:

$routeProvider.when('/secure', {
    templateUrl: '/secure.html', 
    controller: 'Secure',

And then onlyLoggedIn:

var onlyLoggedIn = function ($location,$q,Auth) {
    var deferred = $q.defer();
    if (Auth.isLogin()) {
    } else {
    return deferred.promise;

Simple, works like a charm. If I ever need a directive, I will pull this piece into a service.


This blog post deals with user authentication in AngularJS using directives.

The $route service emits $routeChangeStart before a route change.

If you don't use directives, you can catch that event by calling (you can place it after the code where you define the routes [app.config]). For example:

For full disclosure I use ui.router and this is an adapted code from $stateChangeStart I use in my app

var app = angular.module('app');

app.config(['$routeProvider', function($routeProvider) {
}]);['$rootScope', '$location', 'Auth', function($rootScope, $location, Auth) {
    $rootScope.$on('$routeChangeStart', function(event, currRoute, prevRoute){
        var logged = Auth.isLogin();

        //check if the user is going to the login page
        // i use ui.route so not exactly sure about this one but you get the picture
        var appTo = currRoute.path.indexOf('/secure') !== -1;

        if(appTo && !logged) {


I had the same problem and I did it this way:

var app = angular.module('myModule',["ui-bootstrap"]);

And then listen for a locationchange in the app (this will also trigger onEnter of a page) ($rootScope, $location, $cookieStore) {
 $rootScope.$on("$locationChangeStart", function (event, next, current) {
    //Here you can check whatever you want (servercall, cookie...)

I Hope this helps!