检查经过身份验证的用户是否具有role = admin并阻止访问状态ui-router

时间:2016-05-13 22:15:18

标签: javascript angularjs node.js mongoose

如果经过身份验证的用户具有admin角色并使用它来阻止访问stateprovider中的状态,我将如何获取?

node / server.js函数从经过身份验证的用户获取角色:

app.get('/api/isadmin', ensureAuthenticated, function (req, res) {
  User.findById(req.user, function (err, user) {
    if (req.role !== 'admin') {
        return res.status(403).send('Unauthorized');
    }
    res.send(user);
  });
});

这就是我在努力弄清楚如何让它发挥作用的地方。 我可以得到答复。我设法通过使用工厂和控制器从当前用户获得角色。

angular.module('App')
  .factory('Admin', function ($http) {
     $scope.isAdmin = function () {
      $http.get('http://localhost:3000/api/isadmin')
        .success(function (response) {
            return response.data.role;
        });
  }
});

angular.module('App')
 .controller('AdminCtrl', function ($scope, toastr, Admin) {
   $scope.getAdmin = function () {
      Admin.getAdmin()
        .then(function (response) {
            $scope.role = response.data.role;
            console.log($scope.role);
        })
        .catch(function (response) {
            toastr.error(response.data.message, response.status);
        });
  };
  $scope.getAdmin();
});

我的问题是如何在app.js中实现这一点,以便将其附加到州?我看过这个堆栈问题(this blog post),但我没有让它工作。我使用satellizer作为我的身份验证位,它有一个$ auth.isAuthenticated()函数,我曾试图阻止从未经过身份验证的用户访问状态。这不起作用:

.state('profile', {
      url: '/profile',
      templateUrl: 'Scripts/App/partials/profile.html',
      controller: 'ProfileCtrl',
      resolve: {
          security: ['$q', function ($q, $auth) {
              if (!$auth.isAuthenticated()) {
                  return $q.reject('Not Authorized');
              }
          }]
      }
  });

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

您可以在$stateChangeStart上添加global event listener,并在其处理程序中检查用户授权,如果用户未经授权,只需致电event.preventDefault()以阻止转换发生:

angular.module('App').run([
   '$rootScope', '$auth', '$state', 

   function($rootScope, $auth, $state){

       $rootScope.$on('$stateChangeStart', function(event, toState){
          if(toState.name == 'some states you want to protect'){
              if(!$auth.isAuthenticated()){
                  event.preventDefault();
                  $state.go('home')
              }
          }
      })

  }
])

答案 1 :(得分:0)

您可以使用具有访问权限的用户角色和所需的登录等其他类型的访问来定义每个州。

然后在' $ stateChangeStart'您可以检查所有访问类型的事件,如下例所示。我在上一个项目中使用了相同的方法。

.state('app.view-company-contact', {
    cache: false,
    url: "/company-contacts/:contact_id",
        views: {
            'menuContent': {
                templateUrl: "templates/company-contact-view.html",
                controller: 'ViewCompanyContactCtrl'
            }
    },
    access: {
        requiredLogin: true,
        requiredRole: ['plus-admin', 'plus-standard', 'basic-admin', 'basic-standard']
    }
}) 

.state('app.messages', {
    cache: false,
    url: "/messages",
    views: {
        'menuContent': {
            templateUrl: "templates/messages.html",
            controller: 'MessagesCtrl'
        }
    },
    access: {
        requiredLogin: true,
        requiredRole: ['plus-admin', 'plus-standard']
    }
}) 


.run(function($rootScope, $state, Auth){

    $rootScope.$on('$stateChangeStart', function (event, toState, toStateParams, fromState, fromStateParams) {

        var accessDenied = function(){
            event.preventDefault();

            //do whatever neccessary   
            alert("UNAUTHORIZED_ACCESS");
            //$state.go("login");

        };

        if(angular.isDefined(toState.access)){
            if(toState.access.requiredLogin && !Auth.isUserLoggedIn()) {
                accessDenied();
            }else if(toState.access.requiredRole.indexOf(Auth.getLoggedInUserRole()) < 0){
                accessDenied();
            }else{
                //all checks passed
            }        
        }

    });
})

Auth是一项服务,其中包含一些函数,例如&is; #UserLoggedIn()&#39;和&#39; getLoggedInUserRole()&#39;。