Angular拦截特定的http请求并提示登录

时间:2016-05-26 08:01:56

标签: angularjs http angular-http-interceptors

我正在开发一个有角度的应用程序。这是一个SPA。当用户点击链接时,我正在将个人资料(或myAccount)页面加载到主页中。

<a href="#" ng-click="getProfileData()"/></a>

在我的控制器中:

$scope.getProfileData(){
    $http.get('/profile').then(
        function success(){
        },
        function error(){
        }
    }
}

该链接通过$ http service of angular发出ajax请求。

我想要做的是,当用户点击链接时,在发出ajax请求之前检查他是否已登录。如果没有,请打开登录弹出窗口,登录后继续使用相同的请求。

我已查看$httpProvider.interceptors,但我仍然不知道该怎么做,因为我需要暂停保持$ http请求直到登录完成,修改配置将登录详细信息添加到其中然后继续。

使用拦截器是正确的选择吗?如果是的话,我该如何实现目标?

编辑:

我主要担心的是继续使用相同的请求。即,我不希望用户在登录后再次点击个人资料链接。我可以在发出ajax请求之前检查用户是否已登录。如果他是,那就很好。但如果他没有,他必须登录(在我弹出的模态中),然后他必须再次点击个人资料链接。有没有办法在登录后继续上一个http请求?

2 个答案:

答案 0 :(得分:2)

应用程序中只有三个点应该出现登录模式:

  1. 当您在欢迎页面上并单击“登录”时。
  2. 当您未登录并尝试访问需要登录的页面时。
  3. 当您尝试发出需要登录的请求时(例如:会话过期)。
  4. 确定哪些网页需要登录用户

    考虑到您使用的是ui路由器,您可以通过在路由中附加其他属性来保护应用程序的路由。我们为每个州添加requireLogin属性。

    app.config(function ($stateProvider) {
    
      $stateProvider
        .state('welcome', {
          url: '/welcome',
          // ...
          data: {
            requireLogin: false
          }
        })
        .state('app', {
          abstract: true,
          // ...
          data: {
            requireLogin: true // this property will apply to all children of 'app'
          }
        })
    
    });

    对于不需要登录的路由,我们将requireLogin设置为false。

    捕获尝试的状态更改

    这是我们将捕获尝试的状态更改并检查它们的requireLogin属性的位置。

    app.run(function ($rootScope) {
    
      $rootScope.$on('$stateChangeStart', function (event, toState, toParams) {
        var requireLogin = toState.data.requireLogin;
    
        if (requireLogin && typeof $rootScope.currentUser === 'undefined') {
          event.preventDefault();
          $rootScope.returnToState = toState.url;
          // get me a login modal!
        }
      });
    
    });

    如您所见,如果路线需要登录并且尚未设置$rootScope.currentUser,我们将阻止尝试状态更改并显示模态。

    登录后重定向到最初请求的网址

    最后一部分需要在登录后重定向到最初请求的URL。在我们的app.run中,我们设置了一个变量$rootScope.returnToState = toState.url,我们可以在我们的登录控制器中使用它来重定向。在我们的登录页面控制器中我们可以做这样的事情:

    $scope.login = function(form) {
      $scope.submitted = true;
    
      if(form.$valid) {
        Auth.login({
          email: $scope.user.email,
          password: $scope.user.password
        })
        .then( function() {
          // Logged in, redirect to correct room
          if( $rootScope.returnToState) {
            $location.path($rootScope.returnToState);
          } else {
            //redirect all others after login to /rooms
            $location.path('/home');
          }
        })
        .catch( function(err) {
          $scope.errors.other = err.message;
        });
      }
    };

    如需进一步参考,请参阅此博客文章http://brewhouse.io/blog/2014/12/09/authentication-made-simple-in-single-page-angularjs-applications.html

    这可以帮助您为您的应用构建坚如磐石的授权,我认为您可能正在寻找。

答案 1 :(得分:1)

如果用户已登录,为什么不能再调用另一个函数进行验证。并且基于那个启动你正在那里尝试的ajax请求。像

这样的东西
$scope.getProfileData(){
    if($scope.isLoggedin()){
        $http.get('/profile').then(
            function success(){
            },
            function error(){
            }
        }
    }
};

$scope.isLoggedin = function(){
    // Do some processing and return true/false based on if user is logged-in
};