【问题标题】:How to design angularJS resource based authorization routing?如何设计基于angularJS资源的授权路由?
【发布时间】:2015-03-23 20:14:07
【问题描述】:

我正在使用 angularJS 构建一个博客系统,现在尝试构建一个对某些资源来说易于使用的资源授权流程。 例如,我有以下状态PROPOSALITEMPROPOSALITEM.VIEWPROPOSALITEM.EDITPROPOSALITEM 是通过为子状态提供的:proposalId 解析proposalItem 的父状态。 PROPOSALITEM.VIEW 是允许所有用户访问它的视图状态,PROPOSALITEM.EDIT 是应该只允许 proposal owner 访问的编辑页面。

我从这篇文章中发现有一个漂亮的结构可以在 angularJS 中执行基于 role 的授权流程:Techniques for authentication in AngularJS applications。但是我现在需要的是基于资源的所有权来决定用户是否可以访问该路由。而且我有很多资源,例如 proposal 模型,需要通过所有者授权进行检查。所有这些模型都提供了一个owner 列。有没有解决这个问题的通用解决方案? (我不想把每个模型的授权码放在自己的解析部分,因为它很难维护)

/* Abstract states. Resolve proposalItem */
.state('PROPOSALITEM', {
    abstract: true,
    url: '/proposals/:proposalId',
    template: '<ui-view/>',
    resolve: {
        proposalItem: function($stateParams, ProposalDataService) {
            return ProposalDataService.getItem($stateParams.proposalId);
        }
    }
})
/* View states. Allows all users to access */
.state('PROPOSALITEM.VIEW', {
    abstract: true,
    url: '/view',
    template: '...'
})
/* Edit states. Allows only the proposal owner */
.state('PROPOSALITEM.EDIT', {
    url: '/edit',
    template: '...',
    resolve: {
        proposalItem: function($q, proposalItem, UserDataService) {
            var me = UserDataService.getMe();
            // me: {
            //     _id: '1',
            //     name: '...'
            // }
            if (proposalItem.owner._id === me._id) {
                // Authorized.
                return proposalItem;
            } else {
                // Not authorized.
                var deferred = $q.defer();
                deferred.reject(ERROR_KEYS.NOT_AUTHORIZED);
                return deferred.promise;
            }
        }
    }
})

【问题讨论】:

  • 这是一个非常好的和重要的问题。我实际上对此有一个可行的解决方案,但需要先以模块的形式从我的应用程序中提取它,然后才能发布它。我计划在下周末之前完成,但不确定您是否愿意等待。
  • 即使我知道它也会很兴奋。 @appmux
  • @appmux 我不着急。非常期待您的解决方案!

标签: javascript angularjs angular-ui-router restangular


【解决方案1】:

这就是我通常处理这种情况的方式。创建一个应该处理身份验证的服务:

yourapp.factory('YourResourcePermission', function () {
    return {
        check: function (resource) {
            var me = UserDataService.getMe();
            // return a promise which is resolved with the data
            // if the user has permission, or rejected otherwise.
        }
    };
});

然后你使用这个服务作为你需要的状态的解析参数:

.state('PROPOSALITEM.EDIT', {
url: '/edit',
template: '...',
resolve: function (proposalItem, YourResourcePermission) {  
    return YourResourcePermission.check(proposalItem);
}

})

通过这种方式,您可以让所有权限逻辑远离专用(且可重用)服务中的路由。

如果您有几个状态需要相同的 require 样板,您可以使用 Angular $provide.decorator 自动将您的自定义逻辑注入到您的状态中。 请参阅:https://github.com/christopherthielen/ui-router-extras/blob/master/src/dsr.js#L10https://stackoverflow.com/a/26848546/3794660 作为参考,了解如何装饰 $stateProvider 并创建基本上已设置“resolve”参数的自定义状态类型。

希望这有帮助。

【讨论】:

    猜你喜欢
    • 2020-06-18
    • 2023-03-25
    • 2013-09-22
    • 2021-08-31
    • 2019-07-18
    • 2019-04-15
    • 1970-01-01
    • 1970-01-01
    • 2014-09-12
    相关资源
    最近更新 更多