Ruby on Rails: 使用devise+cancan+rolify創建完整的權限管理系

devise、cancan和rolify這三個組件結合,能夠創建完整而強大的用戶權限模型。html

  • devise介紹,負責用戶註冊、登陸、退出、找回密碼等操做。細節參考devise on github
  • cancan介紹, 負責角色創建、對角色受權、在頁面中根據受權是否顯示元素,以及模型中超出受權時拋出異常。細節參考rolify on github
  • rolify介紹,負責將用戶與角色關聯。細節參考rolify on github

下面就簡單介紹下這三者結合使用的方法,比較淺,深層次的你們本身去看文檔挖掘,這裏僅僅介紹最基本的使用。git

運行環境

這裏我用的是ruby 1.9.3-p484       rails   3.2.16github

新建一個項目

rails new demo --skip-bundle   #跳過bundleruby

在Gemfile裏面添加以下Gem包session

?
1
2
3
4
# add a perfect user verify system
gem 'devise'
gem 'cancan'
gem 'rolify'

而後運行bundle installapp

 執行devise初始化

$ rails generate devise:install

這句命令會產生一個用戶指南,告訴你該作的幾件事請,如下是內容翻譯(已經去除heroku部署的那一條,增長了登陸退出選項的說明):url

1) 肯定你的環境中有一個缺省的URL,config/environments/development.rb:spa

config.action_mailer.default_url_options = { :host => 'localhost:3000' }

若是在production環境, :host 必須設置成應用的真實主機名。.net

2) 肯定已經在config/routes.rb中定義了root_url(注意刪除public下面的index.html), 例如:翻譯

root :to => "home#index"

可使用下面命令生成一個home#index的頁面:

rails g controller home index

3) 在app/views/layouts/application.html.erb中增長消息提醒,例如:

<p class="notice"><%= notice %></p>  <p class="alert"><%= alert %></p> 

4) 不少時候還須要增長登陸、退出的選項:

?
1
2
3
4
5
6
7
     <% if current_user %>
       <%= link_to( '退出' , destroy_user_session_path, :method => :delete ) %> |
       <%= link_to( '修改密碼' , edit_registration_path( :user )) %>
     <% else %>
       <%= link_to( '註冊' , new_registration_path( :user )) %> |
       <%= link_to( '登陸' , new_session_path( :user )) %>
     <% end %><span></span>

5) 若是要定製Devise的view模型,能夠再執行如下語句:

$ rails g devise:views

生成用戶模型(你可使用其餘名稱代替User),並執行數據遷移

$ rails g devise User
$ rake db:migrate

 在Controller中增長認證過濾,便可在訪問該模型頁面時轉向用戶登陸頁面(這自行沒驗證)

在須要認證的模型中,如HomeController,增長下面代碼:

before_filter :authenticate_user!

集成cancan和rolify

cancan提供對資源的受權控制。例如,在視圖中使用can?方法來決定是否顯示某個頁面元素。若是系統角色很是簡單,那麼cancan還在代碼中直接指定常量就能夠支持,具體操做能夠參考官方文檔。但要提供複雜的角色管理,最好的方案,仍是在devise基礎上再集成cancan+rolify。

1. 修改Gemfile,並再次運行bundle install

gem 'cancan'
gem 'rolify'

2. 建立cancan的Ability和rolify的Role

$ rails generate cancan:ability
$ rails generate rolify Role User
$ rake db:migrate

3. 定製devise用戶註冊事件,能夠在註冊時賦予用戶rolify角色,例如,下面的代碼爲首個用戶賦予admin角色:

?
1
2
3
4
5
6
7
8
9
10
11
class ApplicationController < ActionController::Base
      def after_sign_in_path_for(resource)
        if resource.is_a?(User)
          if User.count == 1
            resource.add_role 'admin'
          end
          resource
        end
        root_path
      end
    end

4. 使用cancan能夠爲rolify中創建的角色分配受權資源,例如咱們爲容許admin角色的用戶分配針對全部控制類的」manage」資源,而其餘用戶分配」read」資源:

?
1
2
3
4
5
6
7
8
9
10
class Ability
      include CanCan::Ability
      def initialize(user)
        if user.has_role? :admin
          can :manage , :all
        else
          can :read , :all
        end
      end
    end

5. 以上已經實現了「用戶-角色-權限」的三層權限模型,在view中就可使用了。例如,在Home#index頁面中增長以下代碼:

?
1
2
3
4
5
6
<% if user_signed_in? %>
         <p>The user is loged in .</p>
         <% if can? :manage , :Home %>
           <%= link_to "About" , home_about_path   %>
         <% end %>
     <% end %>

(完)

相關文章
相關標籤/搜索