防止基于HTTP请求的AngularJS中未经授权的URL更改

时间:2019-05-24 16:07:17

标签: angularjs ngroute

我试图基于对授权端点的HTTP GET结果来阻止AngularJS中的导航(该端点与我的Spring Security体系结构相关,但这对这个问题并不重要)。

我将以下内容附加到了附加到顶层模块的run()块上:

    $rootScope.$on("$locationChangeStart", function(event, newUrl, oldUrl) {

        var path = $location.path();
        $http.get('/svc/authorize/view?urlPath=' + path).then(response => {
            if (response.data.result === "NOT_AUTHORIZED") {
                event.preventDefault();
                console.log("Prevented unauthorized location change");
                $ui.showError("Unable to Navigate to " + newUrl);
            }

        });
    });

(注意:$ ui是我们的服务,而不是AngularJS或第三方工具)。

不幸的是,由于$ http.get()是异步的,因此页面会在调用完成之前加载。

如果有帮助,以下是我们的路线定义的示例:

    $routeProvider.when('/problem', {
        templateUrl: '/app/management/problem/problem.tmpl.html',
        controller: 'problemCtrl'
    });

有人可以帮助我吗?我希望我在处理异步调用时犯了一个愚蠢的错误。

1 个答案:

答案 0 :(得分:2)

通常在路由中使用resolve功能以防止未经授权的路由加载。

$routeProvider.when('/problem', {
    templateUrl: '/app/management/problem/problem.tmpl.html',
    controller: 'problemCtrl',
    resolve: {
        authorized: function($http) {
            return $http(someUrl).then(function(response) {
                var data = response.data;
                if (response.data.result === "NOT_AUTHORIZED") {
                    console.log("Prevented unauthorized location change");
                    throw "NOT AUTHORIZED";
                };
                //ELSE
                return data;
            });
        }
    }
});

resolve函数返回承诺时,路由器将在实例化控制器之前等待承诺被解决或拒绝。如果所有的诺言都已成功解决,则注入已解决的诺言的值,并触发$routeChangeSuccess事件。如果任何承诺均被拒绝,则会触发$routeChangeError事件。

有关更多信息,请参见


  

是否有一种方法可以将授权功能与一个地方的所有路由相关联,而不是修改每个单独的路由?

可以将代码重构为使用服务:

$routeProvider.when('/problem', {
    templateUrl: '/app/management/problem/problem.tmpl.html',
    controller: 'problemCtrl',
    resolve: { auth: (AuthService,$route) => AuthService.check($route) }
})

使用$route.current.params访问建议的新路线的参数。