Rails 基于角色的字段验证,你们是怎么做的?

bydmm · 2013年07月12日 · 最后由 everett 回复于 2013年07月13日 · 3267 次阅读

我们的项目遇到这样一个问题,相信大家也经常遇到: 高级管理员可以将任意用户的 role 字段修改为管理员, 而下面的二级管理员,最多将任意用户的 role 字段修改为三级管理员; 超级管理员可以将授权的数目修改为任意值, 而下面的管理员只能小于某个数值等等。

简单的说就是基于角色的字段验证,不知道你们是怎么做的。

我没做过不过据说有个很有名的 gem 专门做这种东西的,好像叫 cancan 还是啥的

cancan是你要找的东西,个人建议你针对 controller#action 做权限控制,而不是针对 model

#3 楼 @leomayleomay 但是我们一个 model 有多个 action 都有修改这个 model 的功能,而且更为重要的是,我们希望能用到 validate 提供的报错到字段的功能。

#2 楼 @jie830413

你这里只是判断用户能不能 update, 而不是控制具体的字段的值。

比如你可以转账(update),但是不能转账超过你拥有钱的数目。

但是,管理员可以 “印钞”,他可以给任何人转账无限多的钱。

这些都是已经进了 update action,但是每个人有限制的做操作。

区分不同的 action。model 加太多校验后续加功能的时候会变成负担。更分层一点可以做些中间操作对象。

#6 楼 @Rei 也就是说,给用户提升等级的时候,不能使用 UsersController 的 update 方法,而是专门写个页面 专门做一个提升用户权限的操作?

#7 楼 @bydmm 是的。在前置过滤器里面检查权限。

@bydmm 5 楼,如果你的 update 有这么多职责,是不是违背了单一职责原则?分出新的 action,或者针对你的 domain 分离出新的 controller 都是可以考虑的方向

几年前做的一个 PHP RBAC, 用 controller#action 做权限控制,希望能在思路上帮到你: https://code.google.com/p/fleastart/

有视频,不用管 PHP,看思路就可以 https://code.google.com/p/fleastart/downloads/list

我思索了一下感觉你们说的很有道理,特别是在 model 加了太多验证,估计对程序的性能也会有很大的影响。 #9 楼 @leomayleomay 如果用户希望在同一个界面修改这些信息的话(四处寻找功能也有些不方便),看来要使用 ajex 来调用这些不同的 action 了。 #10 楼 @Peter 感谢! 我之前学习过 thinkphp 的 RBAC 他采用的就是此类思路。

我想了想,一个 update 接口的话在发布 api 的时候有好处。做成校验的话大概是这样

validates :xxx, length: { maximum: aaa }, :if => :role_admin?
validates :xxx, length: { maximum: bbb }, :if => :role_editor?

attr_accessor :update_role

def role_admin?
  update_role == :admin
end

def role_editor?
  update_role == :editor
end

在 controller 调用的时候

some_object.update_attributes object_params.merge(:update_role => current_user.role_for(@project))

我倾向如 Rei 所言,通过 validates 的 if 选项传入 role 属性的方式。

此外有一个 gem 是做 Model-level authorization 的 https://github.com/stffn/declarative_authorization

个人不太喜欢把权限过滤放在 model 里面 不过,如果你的程序有很多类似的需求,可以考虑下的。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号