angular如何防止用户在注销时直接输入URL来访问页面

时间:2022-07-23 03:37:42

I am using $stateProvider, so I have lots of states.

我使用$ stateProvider,所以我有很多状态。

considering below scenario: user is already logout, and he types url in the browser directly, like www.example.com/home, I should redirect it to the login page, which is www.example.com/login

考虑以下情况:用户已经注销,他直接在浏览器中输入网址,例如www.example.com/home,我应该将其重定向到登录页面,即www.example.com/login

how to implement this? one of the methods is to check if the session is active in run block. is it a good practice to call backend API in the run block?

怎么实现这个?其中一种方法是检查会话在运行块中是否处于活动状态。在运行块中调用后端API是一个好习惯吗?

UPDATE: According to Ryan's suggestion, it calls backend api to check if user is logged in

更新:根据Ryan的建议,它会调用后端api来检查用户是否已登录

$transitions.onBefore({to: 'home'}, function(transition) {
        var $state = transition.router.stateService;
        let promise = jsonService.heartBeat()
        promise.then(data => {
            if(!data.hasOwnProperty('data')) {
                $state.go('login')
            }
        }, () => {
            $state.go('login') 
        })
    });

2 个解决方案

#1


1  

Levi's answer is correct for UI-Router pre-version 1.0. For UI-Router 1.0, the state change events such as $stateChangeStart are deprecated and this will no longer work. You can use the $transitions service instead.

Levi的答案对于UI-Router 1.0版本是正确的。对于UI-Router 1.0,不推荐使用状态更改事件,例如$ stateChangeStart,这将不再起作用。您可以使用$ transitions服务。

function run ($transitions, Auth) {
  // 'to' param is the state name; 'main.**' will match 'main' and all sub-states
  $transitions.onBefore({to: 'main.**'}, function (transition) {
    var $state = transition.router.stateService;
    if (!Auth.isAuthenticated()) {
      $state.go('login');
    }
  });
}

run.$inject = ['$transitions', 'Auth'];

app.run(run);

#2


0  

I ran into same problem months ago. Instead of using resolve, I check if the user is logged when state changes, defining run module and listening $stateChangeStart event, then check if the current state required authentication. If so, check if the user is logged in.

几个月前我遇到了同样的问题。而不是使用resolve,我检查用户是否在状态更改时记录,定义运行模块和监听$ stateChangeStart事件,然后检查当前状态是否需要身份验证。如果是,请检查用户是否已登录。

angular.module('portfolio.manager').config(function ($logProvider, $stateProvider) {
'use strict';

    $stateProvider
    .state('portfolio.manager', {
        url: '/manager',
        resolve: {
            portfolioAuthService: 'portfolioAuthService',

            User: function(portfolioAuthService){
              return portfolioAuthService.getUser();

            },
            Portfolios: function (User, portfolioManagerService) {
                return portfolioManagerService.getPortfolios();
            }
        },
        data: {
            requiredAuthentication: true
        },
        views: {
            'main@': {
                templateUrl: 'app/portfolio/manager/portfolio-manager.html',
                controller: 'PortfolioManagerCtrl'
            },
            'no-portfolios@portfolio.manager': {
                templateUrl: 'app/portfolio/manager/partials/no-portfolios.html'
            },
            'create@portfolio.manager': {
                templateUrl: 'app/portfolio/manager/partials/create.html'
            }
        }
    })

})
.run(run);

  run.$inject = ['$rootScope','$state','loggedIn'];

  function run($rootScope,$state,loggedIn){

    $rootScope.$on('$stateChangeStart',function(e,toState){

      if ( !(toState.data) ) return;
      if ( !(toState.data.requiredAuthentication) ) return;

      var _requiredAuthentication = toState.data.requiredAuthentication;


      if (_requiredAuthentication && !loggedIn.checkUser() ){

        e.preventDefault();
        $state.go('portfolio.login', { notify: false });
        console.log('not authorized');
      }
      return;


    });
  };

#1


1  

Levi's answer is correct for UI-Router pre-version 1.0. For UI-Router 1.0, the state change events such as $stateChangeStart are deprecated and this will no longer work. You can use the $transitions service instead.

Levi的答案对于UI-Router 1.0版本是正确的。对于UI-Router 1.0,不推荐使用状态更改事件,例如$ stateChangeStart,这将不再起作用。您可以使用$ transitions服务。

function run ($transitions, Auth) {
  // 'to' param is the state name; 'main.**' will match 'main' and all sub-states
  $transitions.onBefore({to: 'main.**'}, function (transition) {
    var $state = transition.router.stateService;
    if (!Auth.isAuthenticated()) {
      $state.go('login');
    }
  });
}

run.$inject = ['$transitions', 'Auth'];

app.run(run);

#2


0  

I ran into same problem months ago. Instead of using resolve, I check if the user is logged when state changes, defining run module and listening $stateChangeStart event, then check if the current state required authentication. If so, check if the user is logged in.

几个月前我遇到了同样的问题。而不是使用resolve,我检查用户是否在状态更改时记录,定义运行模块和监听$ stateChangeStart事件,然后检查当前状态是否需要身份验证。如果是,请检查用户是否已登录。

angular.module('portfolio.manager').config(function ($logProvider, $stateProvider) {
'use strict';

    $stateProvider
    .state('portfolio.manager', {
        url: '/manager',
        resolve: {
            portfolioAuthService: 'portfolioAuthService',

            User: function(portfolioAuthService){
              return portfolioAuthService.getUser();

            },
            Portfolios: function (User, portfolioManagerService) {
                return portfolioManagerService.getPortfolios();
            }
        },
        data: {
            requiredAuthentication: true
        },
        views: {
            'main@': {
                templateUrl: 'app/portfolio/manager/portfolio-manager.html',
                controller: 'PortfolioManagerCtrl'
            },
            'no-portfolios@portfolio.manager': {
                templateUrl: 'app/portfolio/manager/partials/no-portfolios.html'
            },
            'create@portfolio.manager': {
                templateUrl: 'app/portfolio/manager/partials/create.html'
            }
        }
    })

})
.run(run);

  run.$inject = ['$rootScope','$state','loggedIn'];

  function run($rootScope,$state,loggedIn){

    $rootScope.$on('$stateChangeStart',function(e,toState){

      if ( !(toState.data) ) return;
      if ( !(toState.data.requiredAuthentication) ) return;

      var _requiredAuthentication = toState.data.requiredAuthentication;


      if (_requiredAuthentication && !loggedIn.checkUser() ){

        e.preventDefault();
        $state.go('portfolio.login', { notify: false });
        console.log('not authorized');
      }
      return;


    });
  };