1

我正在尝试在 AngularJS 中实现基本的身份验证路由。我有一个模型,它有一个返回承诺的授权方法。我希望路由等到该授权函数返回 true 或 false 才能继续,一旦完成,它应该恢复路径或将用户重定向到登录页面。

我认为基本上我需要停止路由,调用该方法,然后恢复或重定向到登录。下面是我到目前为止的代码,但我不确定如何完成暂停/恢复。有任何想法吗?

return angular.module('d', ['ngCookies', 'ngRoute'])
    .config(['$routeProvider', '$locationProvider', '$httpProvider', 
        function ($routeProvider, $locationProvider, $httpProvider) {

            $routeProvider.when('/',
            {
                templateUrl: 'views/home.html',
                controller: 'HomeCtrl'
            });
            $routeProvider.when('/login',
            {
                templateUrl: 'views/login.html',
                controller: 'LoginCtrl'
            });

            $routeProvider.otherwise({ redirectTo: '/404' });
            $locationProvider.html5Mode(true);

            // handle unauthorized requests by redirecting to login page
            $httpProvider.responseInterceptors.push(
                ['$location', '$q', function ($location, $q) {
                    function success(response) {
                        return response;
                    }

                    function error(response) {
                        if (response.status === 401) {
                            $location.path('/login');
                            return $q.reject(response);
                        }
                        else {
                            return $q.reject(response);
                        }
                    }

                    return function (promise) {
                        return promise.then(success, error);
                    }
                }]);

        }])
    .run(['$rootScope', '$location', 'Auth', function ($rootScope, $location, Auth) {

        $rootScope.$on("$routeChangeStart", function (event, next, current) {
            $rootScope.error = null;
            Auth.authorize().then(function(){
                $location.path('/');
            },function(){
                $location.path('/login');
            });
        });

    }]);
4

1 回答 1

2

您的解决方案与我不久前写的原型非常相似。

这个想法是,每当您“触摸”服务器并获得身份验证错误时,都会弹出一个模式窗口,要求在更改 URL 的情况下登录(您让它更改为新的 URL 并留在那里)。

我的实现也是基于检查 401 的拦截器。它依赖于 $rootScope 并将属性“needsLogin”设置为 true。页面模板具有可见的登录模式窗口,needsLogin === true并隐藏了 ng-view(这很重要,因为新路由已加载但它丢失了它的数据)。最后,成功登录后,登录控制器执行$route.reload()然后设置$rootScope.needsLogin = false.

小片段:

<div id="main" role="main" ng-show="needsLogin === false">
    <div ng-view></div>
</div>

<div ng-show="needsLogin === true" ng-include="'views/login.html'" class="overlay"></div>

登录控制器可以是:

function LoginCtrl($scope, $rootScope, $route, $http) {

    $scope.login = function () {
        $http.post( /* Somehow do your login */ )
            .success(function () {
                var deregister = $rootScope.$on('$routeChangeSuccess', function () {
                    // hide login / show ng-view after route has been reloaded
                    $rootScope.needsLogin = false;
                    deregister();
                });
                $route.reload();
            })
            .error(function () {
                /* handle errors */
            });
    };
}

$route.reload()不是整页刷新,它只是重新初始化路由(控制器/视图等)。希望之前被拒绝的调用能够再次运行并且页面会正常。

于 2013-11-04T18:20:16.687 回答