AngularJS - 防止未经过身份验证的用户访问给定路由

Mic*_*zka 5 javascript security angularjs

在我的应用程序用户登录时,我有authService设置内部标志isAuthenticated.现在每次路线改变我都有听众附加到$routeChangeStart检查的事件authService.isAuthenticated().如果没有,它应该重定向到登录路由.

问题是用户刷新页面(所有authService设置都丢失)并再次返回登录(同时仍然在服务器上有有效的会话).这不是我想要的.

我想做的是"阻止"路由更改,直到我获得信息,如果用户已经过身份验证(无论authService是立即验证还是来自服务器,如果没有可用的信息authService,例如刷新后).我有这样的功能authService

        // returns promise
        currentUser: function() {
            if (authService.isAuthenticated()) {
                return $q.when(authService.loggedUser);
            }
            return $http.get('/session').then(function(response) {
                authService.loggedUser = response.user;
                return $q.when(authService.loggedUser);
            });
        }
Run Code Online (Sandbox Code Playgroud)

并希望在事件监听器中使用它.

    $rootScope.$on("$routeChangeStart", function (event, next, current) {
        if(isRouteRestricted(next)) {
            authService.currentUser().then(null, function() {
                $location.path('/login');
            });
        }
    });
Run Code Online (Sandbox Code Playgroud)

问题是它没有按预期工作.我仍然可以在很短的时间内看到目标路线,然后用户被重定向.我相信这是由于承诺的性质,但如何摆脱这种"眨眼"效应?

Roy*_*ove 6

我会在顶级控制器中执行类似这样的操作,这将是刷新页面时调用的第一个控制器(为js中的拼写错误道歉,我是一个coffeescript人):

var authCheck = function (event, next, current) {
    if(isRouteRestricted(next)) {
        authService.currentUser().then(null, function() {
            $location.path('/login');
        });
    }
}

authCheck(null, populateNextSomehow).then(function () {
    // all of your controller code, probably in a separate function
});

$rootScope.$on("$routeChangeStart", authCheck);
Run Code Online (Sandbox Code Playgroud)

这将确保在authCheck完成之前无法调用控制器代码.