【问题标题】:how to restrict view in angularjs application如何限制angularjs应用程序中的视图
【发布时间】:2016-03-11 07:02:58
【问题描述】:

我想限制用户访问 /dashboard 视图和 /add-item 视图或我的 Angular js 应用程序中的任何其他视图。

这是我的路由器

app.config(function($stateProvider, $urlRouterProvider){

        $urlRouterProvider.otherwise('login');

        $stateProvider.
            state('app.dashboard', {
                url: '/dashboard',
                templateUrl: appHelper.viewsPath('dashboard/views/dashboard'),
                controller: 'DashBoardController as DashBordCtrl',
     }).

            // Add Item
            state('app.add-item', {
                url: '/add-item',
                templateUrl: appHelper.viewsPath('item/views/add-item'),
                controller: 'ItemController as ItemCtrl',
            })
        });

登录后,我将令牌存储在本地存储中。如果令牌不存在,我希望用户不要访问任何视图。

这是我的登录控制器

$scope.register = function(credentials){
       LoginService.post(credentials,function(success){
           $state.go('app.add-item');
          SessionService.set("token",success.accessToken);


             },function(error){
       FlashService.showError("Please Enter Valid Email Password");
        });
    }
    }

在出现 401 错误时,我会重定向到这样的登录页面:

app.config(function ($httpProvider) {
   // $http.defaults.headers.common.Authorization = '';
     delete $httpProvider.defaults.headers.common['X-Requested-With'];

    $httpProvider.interceptors.push(function ($location, $q, SessionService, FlashService) {
        return {
            request: function (config) {
                 config.headers = config.headers || {};
                config.headers.Authorization = SessionService.get('token');
                return config;
            },
            responseError: function (response) {
                if (response.status === 401) {
                   SessionService.unset('token');
                    $location.path('/login');
                }
                return $q.reject(response);
            }
        };
    });
});

但是如果我在 url 中输入 /add-item,我的 add-item 页面正在打开,然后突然关闭,因为服务器返回 401,并出现登录页面。如果用户不是,我不想打开任何视图登录。

我是 angularjs 的新手,我很困惑如何做到这一点。请帮忙。

【问题讨论】:

    标签: javascript angularjs


    【解决方案1】:

    如果令牌不存在,您可以保存用户的位置,以便在他登录后将他带回同一页面。您可以在app.js中查看以下代码:

    app.config(function($stateProvider, $urlRouterProvider){    
    
            $stateProvider.
                state('app.dashboard', {
                    url: '/dashboard',
                    templateUrl: appHelper.viewsPath('dashboard/views/dashboard'),
                    controller: 'DashBoardController as DashBordCtrl',
         }).
    
                // Add Item
                state('app.add-item', {
                    url: '/add-item',
                    templateUrl: appHelper.viewsPath('item/views/add-item'),
                    controller: 'ItemController as ItemCtrl',
                })
     $urlRouterProvider.otherwise('login');
            });
    

    $urlRouterProvider.otherwise('login') 替换为 app.config 中的 $urlRouterProvider.otherwise('app/dashboard') 。如果是 $urlRouterProvider.otherwise('login') ,你有一个令牌,抛出登录页面静止。

     app.config(function ($httpProvider) {
           // $http.defaults.headers.common.Authorization = '';
             delete $httpProvider.defaults.headers.common['X-Requested-With'];
    
            $httpProvider.interceptors.push(function ($location, $q, SessionService, FlashService) {
                return {
                    request: function (config) {
                         config.headers = config.headers || {};
                        config.headers.Authorization = SessionService.get('token');
                        return config;
                    },
                    responseError: function (response) {
                        if (response.status === 401) {
                           SessionService.unset('token');
                            $location.path('/login');
                        }
                        return $q.reject(response);
                    }
         if (!SessionService.get('token');) {
                        /* You can save the user's location to take him back to                 the same page after he has logged-in */
                        $rootScope.savedLocation = $location.url();
    
                        $location.path('/login');
                    }
                };
            });
        });
    

    【讨论】:

    • 感谢回复,但是当我在 url 中写入 /add-item 时,我的 add-item 页面仍然闪烁一秒钟,然后打开登录页面。我的问题是如果令牌不存在,我希望用户在登录页面上,只要网址是..
    【解决方案2】:

    您应该在路由配置中使用 resolve。示例:

    state('app.add-item', {
                url: '/add-item',
                templateUrl: appHelper.viewsPath('item/views/add-item'),
                controller: 'ItemController as ItemCtrl',
                resolve: ['SomeService', function(SomeService) {
                    return SomeService.getDataFromApi();
                }]
            })
    

    看这个例子,如果 SomeService 返回 401,意味着错误,路由控制器将永远不会实例化,因此您无法访问视图。你的拦截器仍然会做他的工作,并在 401 发生时重定向到登录,但现在它会顺利发生并且没有视图闪烁。

    这是一个很好的方法,它将解决您的问题以及您以后可能遇到的其他问题。

    【讨论】:

    • 感谢您的回复。我认为它会起作用,但我可以在解析中检查令牌,而不是 401 错误。
    • 重点是,只能检查token是否存在。您无法检查令牌是否有效,这就是重点。您要进行的检查仅适用于首次使用的用户,并且可能适用于在上次访问时手动注销的用户。
    • 那么我是否必须提供一些服务来访问 api 并获取数据,无论令牌是否有效?然后将其注入每个解析部分?
    • 不,拦截器保持原样,您不执行特殊调用以查看令牌是否有效。您现在需要做的就是在您的路线中设置解析块。因此,您无需从特定控制器调用 api,而是在解析中像这样调用它,然后将数据提供给控制器(如果您不理解,请在 uiRoutes 文档中阅读更多相关信息)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-31
    • 1970-01-01
    • 2018-06-12
    • 2014-03-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多