http-redirectauthenticationangularjsangularjs-routingangularjs-authentication

Redirect after user has logged in


I'm pretty new to Angular, and right now I'm just trying to get all my routes set up and working as I'd like.

Setup: When a user navigates to certain pages (/settings for this example) the app should check if there is a user already logged in. If there is continue as usual. Otherwise the user should go to the login page (/login).

What I'd like: After the user has successfully logged in they should go to the page they were originally trying to get to (/settings)

My question: Is there an "Angular way" to remember where the user was trying to go to?

Relevant code:

app.js

  .when('/settings', {
      templateUrl: '/views/auth/settings.html',
      controller: 'SettingsCtrl',
      resolve: {
        currentUser: function($q, $location, Auth) {
          var deferred = $q.defer();

          var noUser = function() {
            //remember where the user was trying to go
            $location.path("/login")
          };

          Auth.checkLogin(function() {
            if (Auth.currentUser()) {
              deferred.resolve(Auth.currentUser());
            } else {
              deferred.reject(noUser());
            }
          });

          return deferred.promise;
        }
      }
    })

login.js

  $scope.submit = function() {
    if(!$scope.logInForm.$invalid) {
      Auth.login($scope.login, $scope.password, $scope.remember_me)
      //go to the page the user was trying to get to
    }
  };

Much thanks to John Lindquist for the video which got me this far.


Solution

  • First off, you do not want to redirect the user to a login page.

    An ideal flow in a single page web app is as follows:

    1. A user visits a web site. The web site replies with the static assets for the angular app at the specific route (e.g. /profile/edit).

    2. The controller (for the given route) makes a call to an API using $http, $route, or other mechanism (e.g. to pre-fill the Edit Profile form with details from the logged in user's account via a GET to /api/v1/users/profile)

    3. If/while the client receives a 401 from the API, show a modal to login, and replay the API call.

    4. The API call succeeds (in this case, the user can view a pre-filled Edit Profile form for their account.)

    How can you do #3? The answer is $http Response Interceptors.

    For purposes of global error handling, authentication or any kind of synchronous or asynchronous preprocessing of received responses, it is desirable to be able to intercept responses for http requests before they are handed over to the application code that initiated these requests. The response interceptors leverage the promise apis to fulfil this need for both synchronous and asynchronous preprocessing.

    http://docs.angularjs.org/api/ng.$http

    Now that we know what the ideal user experience should be, how do we do it?

    There is an example here: http://witoldsz.github.com/angular-http-auth/

    The example is based on this article:

    http://www.espeo.pl/2012/02/26/authentication-in-angularjs-application

    Good luck and happy Angularing!