cancan 笔记

来源:互联网 发布:paxos算法推导 编辑:程序博客网 时间:2024/05/12 11:47

cancan 笔记

ruby-on-rails cancan Rei Created at 9 months ago 

CanCan 使用

https://github.com/ryanb/cancan

基本流程

  1. Install
  2. Define Abilities
  3. Check Abilities & Authorization

Install

gem “cancan”

Define Abilities

生成权限定义文件

权限定义在类 Ability 中,放在 model,安装之后生成

rails g cancan:ability

定义权限

CanCan 的权限定义的上下文可以使用这5个元素:动作(action),主题类,主题类的实例,用户实例,条件判断语句。

例一:

class Ability  include CanCan::Ability  def initialize(user)    user ||= User.new # guest user (not logged in)    if user.admin?      can :manage, :all    else      can :read, :all    end  endend

:manage,:read 称为权限的 action,内置对 REST 7 种 action 的支持,也可以随意定义 action,其实就是一个符号。

例二(Hash of Conditions)

can :read, Project, :active => true, :user_id => user.id

user 可以阅读 active 为 true,user_id 等于 user.id 的 project。

附:在 controller 中,可以用 projects = Project.accessible_by(current_ability) 获取当前用户允许阅读(:read)的 project。这个便捷方法称为 Fetching Records

例三(Conditions with Block):

如果权限非常复杂,可以使用 block 作为条件。当 block 返回 ture 时权限通过,否则拒绝。

can :update, Project do |project|  project.priority < 3end

例四(Overriding All Behavior)

更直接地定义权限,更复杂的定义可以用这种方式。但基本上用例三的 Block 就足够了。

can do |action, subject_class, subject|  # ...end

Check Abilities & Authorization

can?、cannot? 判断

在 controller 和 view 中可以使用 can? 和 cannot? 方法判断用户对资源的访问权。

例:

controller:

can? :destroy, @projectcannot? :destroy, @project

view:

<% if can? :create, Project %>  <%= link_to "New Project", new_project_path %><% end %>

注意:如果权限定义使用了条件判断,那么对类的权限检查总会返回 true

can :read, Project, :priority => 3can? :read, Project # returns true

authorize!

与 can? cannot? 的区别是授权失败时候会抛出 CanCan::AccessDenied 异常,可以通过在 ApplicationController.rb 里面用 捕获

in controller :

authorize! :read, Article, :message => "Unable to read this article."

in application_controller:

rescue_from CanCan::AccessDenied do |exception|  redirect_to root_url, :alert => exception.messageend

应用场合

基于用户角色的授权

假设 user 有 role? 方法

# in Ability#initializeif user.role? :moderator  can :manage, Postendif user.role? :admin  can :manage, Threadendif user.role? :superadmin  can :manage, Forumend
原创粉丝点击