权限控制[2] CanCan + Rolify + Devise

在model/ability.rb中定义权限

Reference: Defining Abilities
基础权限

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

自定义权限集合

def initialize(user)
  user ||= User.new

  alias_action :create, :read, :update, :destroy, to: :crud

  can :crud, User
  can :invite, User
end

利用Hash条件筛选定义

class Photo
  has_and_belongs_to_many :groups
  scope :unowned, includes(:groups).where(groups: { id: nil })
end

class Group
  has_and_belongs_to_many :photos
end

class Ability
  def initialize(user)
    user ||= User.new # guest user (not logged in)
    can :read, Photo, Photo.unowned do |photo|
      photo.groups.empty?
    end
  end
end

利用代码块来定义权限

Reference: Defining Abilities with Blocks

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

重写默认方法

Reference: Changing Defaults
利用cancancan+rolify+devise做权限控制,如果你使用的是自己建的表,名字有区别,可能会导致current_user无法正常使用。比方说,项目中的用户表是buser,那么用device之后,当前用户就应该是current_buser,且需要重写cancancan的默认加载方法。
直接把方法写在ApplicaitonController中即可。

CanCanCan makes two assumptions about your application.

You have an Ability class which defines the permissions.
You have a current_user method in the controller which returns the current user model.
You can override both of these by defining the current_ability method in your ApplicationController. The current method looks like this.

def current_ability
  @current_ability ||= Ability.new(current_user)
end
The Ability class and current_user method can easily be changed to something else.

# in ApplicationController
def current_ability
  @current_ability ||= AccountAbility.new(current_account)
end

Restful Controller中的权限控制

Reference:
- Authorizing controller actions
- rails基于devise+cancancan+rolify的简单权限控制实现
在controller中做权限控制,你可以控制整个controller,也可以逐个方法做局部控制。
针对有对应资源的controller,只需要在开头加上控制语句即可。

You can use the authorize! method to manually handle authorization in a controller action. This will raise a CanCan::AccessDenied exception when the user does not have permission. See Exception Handling for how to react to this.

def show
  @project = Project.find(params[:project])
  authorize! :show, @project
end
However that can be tedious to apply to each action. Instead you can use the load_and_authorize_resource method in your controller to load the resource into an instance variable and authorize it automatically for every action in that controller.

class ProductsController < ActionController::Base
  load_and_authorize_resource
end
This is the same as calling load_resource and authorize_resource because they are two separate steps and you can choose to use one or the other.

class ProductsController < ActionController::Base
  load_resource
  authorize_resource
end

针对没有对应资源的controller,我们也可以为它指定需要加载的类。

class LogController < ApplicationControlle
    load_and_authorize_resource :class => "Production" 
     def record_log
        ........ 
     end

NonRestful Controller中的权限控制

Reference:Non RESTful Controllers
针对部分controller与资源不挂钩的情况,我们也可以进行单独控制。
注意,此时我们只能只能进行逐个方法的局部控制,不能统一控制controller。
在定义权限的时候,注意两个参数必须都是ruby的符号对象。

For example, let's say we have a controller which does some miscellaneous administration tasks such as rolling log files. We can use the authorize! method here.

class AdminController < ActionController::Base
  def roll_logs
    authorize! :roll, :logs
    # roll the logs here
  end
end
And then authorize that in the Ability class.

can :roll, :logs if user.admin?
Notice you can pass a symbol as the second argument to both authorize! and can. It doesn't have to be a model class or instance. Generally the first argument is the "action" one is trying to perform and the second argument is the "subject" the action is being performed on. It can be anything.

页面的权限控制

Reference:Checing Ablities
当我们在model/ablitiy.rb中定义完所有权限之后,我们可以在页面上直接使用。

<% if can? :create, Project %>
  <%= link_to "New Project", new_project_path %>
<% end %>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值