论坛首页 编程语言技术论坛

Rails:对同一个model的不同访问权限的访问控制的设计

浏览 3540 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-02-01  
想和大家讨论一个rails的访问控制的设计问题。

假如我有一个user的model,实现对它的增、删、改、列表等功能。普通情况下,我们会实现类似于Scaffold生成的代码。默认进去一个user列表,然后每个user后面有edit, delete等之类的功能。同时列表上面有add的按钮。

假如我要加入权限控制,比如有的人只能看到列表。有的能看到列表和使用add功能,有的人能看到列表并且使用所有的功能。三种不同权限的人都可以看到列表,只不过对列表的操作不同。为了实现这样的访问控制,可以不同的设计。

通常,我会把所有的功能操作都放在一个controller中,这样就只有一套view。但是在显示add, edit, delete之类的按钮时进行判断,只有有相应的权限的人才可以看到这些按钮,进一步在相应的action里面也做相应的判断。 这样可以实现,但是总的来说感觉很凌乱。结构不够好,虽然可以把显示、隐藏操作按钮的逻辑放在helper里面还是感觉乱。

另外一种方法就是把不同的操作放在不同的controller里面,并且对不同的操作权限的人写不同view。这样就几乎完全独立开了。独立的controller,独立的view等等。 就没有那么繁杂的通过权限来判断是否显示按钮的逻辑了。不过就不是很DRY了,类似的列表要写好几次。

在这种情况,不知道大家是怎么设计的?谢谢指点。
   发表时间:2009-02-02  
看看 ActiveScaffold

0 请登录后投票
   发表时间:2009-02-02  
好像activerecord没有直接和我的问题相关阿。
如果给每个model创建一个独立的admin的功能,那么就相当于我说的第二种方案,创建独立的controller以及相应的view.
0 请登录后投票
   发表时间:2009-02-02  
好像有一些demo是和权限控制相关的,我研究一下,多谢open2ye
0 请登录后投票
   发表时间:2009-02-05  
这个问题我也思考过。
我认为ActiveScaffold的实现思路有问题,不应该将判断权限的事情搞到ActiveRecord里面去。
ActiveScaffold为了让模型能够鉴权,将当前用户信息也植入到模型中(参考其ActiveRecordPermissions),这显然是一个跨界缺陷,这导致AR手伸得太长了。
我认为权限的处理,应该采用Controller的filter来,controller是知道当前用户是谁,而model不应该管当前用户是谁。
1 请登录后投票
   发表时间:2009-02-05  
我会单独做一个模块来完成。

把每个/controller/action 和 user group 关联起来。
如果user 关联了 /users/add 那么它就可以add, 不然就不可以
每次用户操作都需要读一次数据库来确定权限。
0 请登录后投票
   发表时间:2009-02-10  
kadvin 写道
我认为权限的处理,应该采用Controller的filter来,controller是知道当前用户是谁,而model不应该管当前用户是谁。

我也认同这个想法。
Model里面只是处理数据,然而谁有什么样的权限做什么样的事情,应该由controller判断。
0 请登录后投票
   发表时间:2009-02-10  
我的项目刚好做了一个简易的实现,这是migrate

Action 关联 Group
class CreateAdmActions < ActiveRecord::Migration
  def self.up
    create_table :adm_actions do |t|
      t.string :ctrl, :null=>false, :limit=>31
      t.string :actn, :null=>false, :limit=>31
      t.timestamps
    end
    add_index :adm_actions,:actn
    add_index :adm_actions,:ctrl
    add_index :adm_actions,[:ctrl,:actn]

    create_table(:adm_actions_adm_groups,:id=>false) do |t|
      t.integer :adm_action_id, :null=>false
      t.integer :adm_group_id , :null=>false
      t.timestamps
    end
    add_index :adm_actions_adm_groups, :adm_action_id
    add_index :adm_actions_adm_groups,:adm_group_id
    add_index :adm_actions_adm_groups, [:adm_action_id,:adm_group_id],:unique=>true
    
  end

  def self.down
    drop_table :adm_actions_adm_groups
    drop_table :adm_actions
  end
end




class CreateAdmGroups < ActiveRecord::Migration
  def self.up
    create_table :adm_groups do |t|
      t.string :name, :limit=>15, :null=>false
      t.text :desc
      t.timestamps
    end
    add_index :adm_groups, :name, :unique=>true

    create_table(:adm_groups_users,:id=>false) do |t|
      t.integer :adm_group_id, :null=>false
      t.integer :user_id, :null=>false
      t.timestamps
    end
    add_index :adm_groups_users, [:adm_group_id,:user_id], :unique=>true
    add_index :adm_groups_users, :adm_group_id
    add_index :adm_groups_users, :user_id
  end

  def self.down
    drop_table :adm_groups_users
    drop_table :adm_groups
  end
end



不过我并不是很满意,感觉实现起来比较容易,先用着。
activescaffold让我的感觉是可以作为一个起点,但是迟早要丢掉。
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics