在Rails中用CanCan进行权限控制

一个网站一般都有后台管理功能,后台管理的人员分系统管理员和普通管理员,如果是论坛的话,前台又有好几个角色,版主,总版主,VIP用户,认证用户等等,如果自己去重新去设计的话费时不说可能还不到位,最好有插件,简单配置一下,就可以用了,gem的设计也是出于这个理念,google了一番,CanCan用得比较多,就用这个吧。
1.安装CanCan,编辑Gemfile

gem 'cancan', '~> 1.6.7'

执行

$ bundle install
$ rails generate
...
Cancan:
  cancan:ability
...

2.定义Ability类

$ rails g cancan:ability
    create  app/models/ability.rb
#app/models/ability.rb
class Ability
  include CanCan::Ability
 
  def initialize(user)
    # Define abilities for the passed in user here. For example:
    #
    #   user ||= User.new # guest user (not logged in)
    #   if user.admin?
    #     can :manage, :all
    #   else
    #     can :read, :all
    #   end
    #
    # The first argument to `can` is the action you are giving the user permission to do.
    # If you pass :manage it will apply to every action. Other common actions here are
    # :read, :create, :update and :destroy.
    #
    # The second argument is the resource the user can perform the action on. If you pass
    # :all it will apply to every resource. Otherwise pass a Ruby class of the resource.
    #
    # The third argument is an optional hash of conditions to further filter the objects.
    # For example, here the user can only update published articles.
    #
    #   can :update, Article, :published => true
    #
    # See the wiki for details: https://github.com/ryanb/cancan/wiki/Defining-Abilities
  end
end

3.创建Role model

$ rails g model role

4.User和Role之间添加关联

class User
  include Mongoid::Document
...
  embeds_many :roles
...
end
class Role
  include Mongoid::Document
  field :name
  embedded_in :user
end

5.在User类中添加role?函数

def role?(role)
  return !!self.roles.where({"name" => /#{role.to_s}/}).first
end

6.编辑app/models/ability.rb文件

class Ability
  include CanCan::Ability
 
  def initialize(user)
    user ||= User.new
    if user.role? :admin
      can :manage, :all
    elsif user.role? :user
      can :read, Forum
    end
  end
end

7.编辑需要添加权限的controller

class ForumsController < ApplicationController
  before_filter :authenticate_user!
  #load_and_authorize_resource 和 authorize_resource 两个方法都可以,不同的是load_and_authorize_resource会先加载本类model的值
  authorize_resource
  def index
    @forums = Forum.all()
    #authorize! :read, @forums 对单个action进行权限判断
  end
 
  def new
    @forum = Forum.new
  end
end

也可以在view中进行权限判断,方法是can? 和 cannot?

# app/views/forums/index.html.haml
- if can? :create, @forums
  = link_to "创建", new_forum_path

8.处理未授权的访问的方法
如果权限认证失败,cancan会抛出一个CanCan::AccessDenied的异常,你可以在ApplicationController中捕获它来显示自己内容。

class ApplicationController < ActionController::Base
...
  rescue_from CanCan::AccessDenied do |exception|
    redirect_to root_url, :alert => exception.message
  end
...
end

你可能感兴趣的:(user,filter,Class,action,Rails,include)