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

原文中有些問題,我按本身的實踐稍稍作了些修改。不知到是否是Gem升級到最新的緣故,不過仍是解決了。 html

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

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

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

運行環境

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

新建一個項目

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

在Gemfile裏面添加以下Gem包 app

# add a perfect user verify system
gem 'devise'
gem 'cancan'
gem 'rolify'

而後運行bundle install url

 執行devise初始化

$ rails generate devise:install

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

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

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

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

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) 不少時候還須要增長登陸、退出的選項:

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

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角色:

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」資源:

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頁面中增長以下代碼:

<% if user_signed_in? %>
        <p>The user is loged in.</p>
        <% if can? :manage, :Home %>
          <%= link_to "About", home_about_path   %>
        <% end %>
    <% end %>
(完)
相關文章
相關標籤/搜索