现在的位置: 首页 > 综合 > 正文

cancan 笔记

2018年04月19日 ⁄ 综合 ⁄ 共 1740字 ⁄ 字号 评论关闭

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
  end
end

: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 < 3
end

例四(Overriding All Behavior)

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

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

Check Abilities & Authorization

can?、cannot? 判断

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

例:

controller:

can? :destroy, @project
cannot? :destroy, @project

view:

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

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

can :read, Project, :priority => 3
can? :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.message
end

应用场合

基于用户角色的授权

假设 user 有 role? 方法

# in Ability#initialize

if user.role? :moderator
  can :manage, Post
end
if user.role? :admin
  can :manage, Thread
end
if user.role? :superadmin
  can :manage, Forum
end

抱歉!评论已关闭.