【问题标题】:Group-level role authorization in Node.jsNode.js 中的组级角色授权
【发布时间】:2014-10-23 09:36:45
【问题描述】:

我在 Express 应用程序中使用 Passport.js 进行身份验证。

我需要实施基于角色的授权,并且我倾向于使用连接角色 因为它很容易与 Passport 集成。

我了解基本角色的授权方式(例如管理员、用户、编辑),但我需要 在组的上下文中授权这些角色。

一个简化的用例是: 页面管理员只能查看和编辑他正在管理的页面的详细信息。

基本角色如何与组分配相结合,是否一定是角色步骤 还是在护照认证中检查资源访问权限的问题?

【问题讨论】:

    标签: node.js connect acl roles passport.js


    【解决方案1】:

    这就是我所做的。它没有完全使用护照,但效果很好(我从 Ghost 那里得到灵感)。我不知道这是一个好习惯还是安全,但这里是:

    config.json 包含权限:

    "user_groups": {
        "admin": {
          "full_name": "Administrators",
          "description": "Adminsitators.",
          "allowedActions": "all"
        },
        "modo": {
          "full_name": "Moderators",
          "description": "Moderators.",
          "allowedActions": ["mod:*", "comment:*", "user:delete browse add banish edit"]
        },
        "user": {
          "full_name": "User",
          "description": "User.",
          "allowedActions": ["mod:browse add star", "comment:browse add", "user:browse"]
        },
        "guest": {
          "full_name": "Guest",
          "description": "Guest.",
          "allowedActions": ["mod:browse", "comment:browse", "user:browse add"]
        }
      }
    

    然后是permissions.coffee文件

    mongoose = require("mongoose")
    ###
    This utility function determine whether an user can do this or this
    using the permissions. e. g. "mod" "delete"
    
    @param userId the id of the user
    @param object the current object name ("mod", "user"...)
    @param action to be executed on the object (delete, edit, browse...)
    @param owner the optional owner id of the object to be "actionned"
    ###
    exports.canThis = ((userId, object, action, ownerId, callback) ->
      User = mongoose.model("User")
      if typeof ownerId is "function"
        callback = ownerId
        ownerId = undefined
      if userId is ""
        return process(undefined, object, action, ownerId, callback)
      User.findById(userId, (err, user) ->
        if err then return callback err
        process(user, object, action, ownerId, callback)
      )
    ).toPromise(@)
    
    process = (user, object, action, ownerId, callback) ->
      if user then role = user.role or "user"
      group = config.user_groups[role or "guest"]
      if not group then return callback(new Error "No suitable group")
    
      # Parses the perms
      actions = group.allowedActions
      for objAction in actions when objAction.indexOf object is 0
        # We get all the allowed actions for the object and group
        act = objAction.split(":")[1]
        obj = objAction.split(":")[0]
        if act.split(" ").indexOf(action) isnt -1 and obj is object
          return callback true
    
      callback false
    
    config = require "../config"
    

    然后是一些用法(使用Q):

    exports.edit = (userid, name) ->
      # Q promise
      deferred = Q.defer()
      # default value
      can = false
      # We check wheteher it can or not
      canThis(userid, "user", "edit").then((can)->
        if not userid
          return deferred.reject(error.throwError "", "UNAUTHORIZED")
        User = mongoose.model "User"
        User.findOne({username: name}).select("username location website public_email company bio").exec()
      ).then((user) ->
        # Can the current user do that?
        if not user._id.equals(userid) and can is false
          return deferred.reject(new Error())
        # Done!
        deferred.resolve user
      ).fail((err) ->
        deferred.reject err
      )
      deferred.promise
    

    【讨论】:

    • 谢谢@Vinz243!尽管据我了解,授权是全局性的,因为管理员将能够执行管理员允许的所有操作。我也在寻找一种通过组关联进行限制的方法,你在做类似的事情吗?
    • @BarakChamo “我正在寻找一种通过组关联进行限制的方法” 对不起,我不明白你的意思。
    • 例如:帖子的编辑可以编辑他的帖子,但不能编辑其他人的帖子。所以他是一个角色的编辑,但他也与帖子相关联。
    • # 当前用户可以这样做吗? if not user._id.equals(userid) and can is false return deferred.reject(new Error()) # Done!
    猜你喜欢
    • 1970-01-01
    • 2013-09-28
    • 1970-01-01
    • 2012-04-11
    • 2014-01-17
    • 2014-05-08
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    相关资源
    最近更新 更多