Divert to alternate homepage if user is not logged in using UI-Router & AngularJS

对着背影说爱祢 提交于 2019-11-27 19:04:04

问题


I would like to have two home pages, the first would be for users who have not logged in and the second for users that are logged in.

This is my current set up:

.config(function ($stateProvider, $urlRouterProvider, $locationProvider, $httpProvider) {
    $urlRouterProvider
      .otherwise('/');

    $locationProvider.html5Mode(true);
    $httpProvider.interceptors.push('authInterceptor');
  })

  .factory('authInterceptor', function ($rootScope, $q, $cookieStore, $location) {
    return {
      // Add authorization token to headers
      request: function (config) {
        config.headers = config.headers || {};
        if ($cookieStore.get('token')) {
          config.headers.Authorization = 'Bearer ' + $cookieStore.get('token');
        }
        return config;
      },

      // Intercept 401s and redirect you to login
      responseError: function(response) {
        if(response.status === 401) {
          $location.path('/login');
          // remove any stale tokens
          $cookieStore.remove('token');
          return $q.reject(response);
        }
        else {
          return $q.reject(response);
        }
      }
    };
  })

  .run(function ($rootScope, $location, Auth) {
    // Redirect to login if route requires auth and you're not logged in
    $rootScope.$on('$stateChangeStart', function (event, next) {
      if (next.authenticate && !Auth.isLoggedIn()) {
        $location.path('/login');
      }
    });
  });
.config(function ($stateProvider) {
        $stateProvider
          .state('main', {
            url: '/',
            templateUrl: 'app/main/main.html',
            controller: 'MainCtrl',
            title: 'Home',
            mainClass: 'home',
            headerSearch: true
          });
      });

How could I reconfigure this so I could do something like the following:

.config(function ($stateProvider) {
    $stateProvider
      .state('welcome', {
        url: '/',
        templateUrl: 'app/welcome/welcome.html',
        controller: 'WelcomeCtrl',
        title: 'Welcome',
        mainClass: 'welcome',
        isLoggedIn: false
      });
     $stateProvider
      .state('main', {
        url: '/',
        templateUrl: 'app/main/main.html',
        controller: 'MainCtrl',
        title: 'Home',
        mainClass: 'home',
        isLoggedIn: true
      });
  });

回答1:


Just wanted to show, how we can manage authentication driven access to states. Based on this answer and its plunker, we can enrich each state (which should be accessible only for authenticated users) with a data setting, explained here: Attach Custom Data to State Objects (cite:)

You can attach custom data to the state object (we recommend using a data property to avoid conflicts)...

So let's have some states with public access:

// SEE no explicit data defined
.state('public',{
    url : '/public',
    template : '<div>public</div>',
})
// the log-on screen
.state('login',{
    url : '/login',
    templateUrl : 'tpl.login.html',
    controller : 'UserCtrl',
})
... 

And some with private access:

// DATA is used - saying I need authentication
.state('some',{
    url : '/some',
    template : '<div>some</div>',
    data : {requiresLogin : true }, // HERE
})
.state('other',{
    url : '/other',
    template : '<div>other</div>',
    data : {requiresLogin : true }, // HERE
})

And this could be hooked on on the state change:

.run(['$rootScope', '$state', 'User', function($rootScope, $state, User)
{

  $rootScope.$on('$stateChangeStart'
    , function(event, toState, toParams, fromState, fromParams) {

    var isAuthenticationRequired =  toState.data 
          && toState.data.requiresLogin 
          && !User.isLoggedIn
      ;

    if(isAuthenticationRequired)
    {
      event.preventDefault();
      $state.go('login');
    }
  });
}])

See all that in action here

There is similar Q & A were I try to show the concept of redirecting Authenticated and Not Authenticated user:

  • Angular UI Router: nested states for home to differentiate logged in and logged out

maybe that could help to get some idea, how we can use ui-router, and its event '$stateChangeStart' to hook on our decision manager - and its forced redirecting...




回答2:


the code should be something like this

     $rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState)                { //, fromParams
       console.log(toState.name + "," + fromState.name);
        if(fromState.name === "") {
          if (Auth.isLoggedIn()) {
              $state.go('welcome');
               event.preventDefault();
          } else {
            $state.go('home');
               event.preventDefault();
        } else {
           if (toState.authenticate && !Auth.isLoggedIn()) {
               $toState.go('login');
               event.preventDefault();
           }
        }
    }

so if user entering the application, then if he is logged in take him to welcome else take him to home.

once he is inside, then if he hits some route which needs auth.. then redirect him to login page..

sorry if i did not understood you requirement fully...




回答3:


.config(function ($stateProvider,$rootScope) {
$stateProvider
  .state('welcome', {
    url: '/',
    templateUrl: 'app/welcome/welcome.html',
    controller: 'WelcomeCtrl',
    onEnter: function() {
      if (userIsLoggedIn()) {
         $stateProvider.go('home');
      }
  });

});




回答4:


I had problem like this and I solved it like this

 .run(function ($rootScope, $location, AuthService) {

        // start showing PRELOADER because we doing async call and we dont know when it will be resolved/rej
        AuthService.checkLoginStatus().then(
            (resp) => {
                // fire logged in user event
                $rootScope.$broadcast('userLogged',resp);
                $location.path(YourHomePageUrl);

            },
            (err)=> {  
                // Check that the user is not authorized redirect to login page                  
                    $location.path(loginURL);
                }
            }).finally(
            ()=> {
                // finnaly Set a watch on the $routeChangeStart
                /// Hide PRELOADER
                $rootScope.$on('$routeChangeStart',
                    function (evt, next, curr) {
                      if (!AuthService.isLoggedIn()) {
                                $location.path(art7.API.loginURL);
                            }

                    });
            }
        )


    });

and im not using interceptor for handling 401 not authorized errors, thats my solution



来源:https://stackoverflow.com/questions/25015339/divert-to-alternate-homepage-if-user-is-not-logged-in-using-ui-router-angularj

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!