rails+devise+cancancan+rolify注冊登錄多角色權限管理


Mac環境

Ruby 2.4.1

Rails 5.1.2

 

進入正題,本章主要是解決多角色權限問題,使用 devisecancancanrolify 。 

注:所有 $ 開頭的都是終端里輸入的,其它都是項目里面的文檔加入的。

1、先創建好新的項目

$ rails new demo

  

2、打開Gemfile,加入以下gem

gem 'devise'
gem 'cancancan'
gem 'rolify'

  

3、進入項目文件俠里

$ cd demo

  

4、安裝剛剛加入的gem

$ bundle install

  

5、安裝devise

$ rails g devise:install

  

6、打開config/environments/development.rb 文件,在里面輸入

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

  

7、打開 config/routes.rb,在里面輸入

root to: "home#index"

  

8、打開app/views/layouts/application.html.erb 文件,在<%= yield %>前面加入以下代碼:

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

  

9、在終端輸入以下代碼:

$ rails g devise:views

  

10、現在添加一個提前routes.rb里提到的home目錄和index文件,在終端執行以下代碼:

$ rails g controller home index

  

11、在終端輸入以下代碼:

$ rails g devise user

    

12、創建一個list列表,這個list是用scaffold(腳手架)直接產生出來,在終端下輸入以下代碼:

$ rails g scaffold list name idcard phone

  

13、在終端下輸入以下代碼:

$ rails db:migrate

 

 14、打開app/controllers/lists_controller.rb 和 app/controllers/home_controller.rb,把以下代碼輸入相應的位置:

before_action :authenticate_user!

  注:這個是Devise的提供的方法,驗證登錄后才能打開這個list頁面

 

15、增加一個注冊登錄的導航,按下方法操作,打開app/views/layouts/application.html.erb,在<%= yield %>前面輸入以下代碼:

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

  

16、接下來集成cancancan、rolify

$ rails generate cancan:ability
$ rails generate rolify Role User

  

 17、打開db/migrate/20171217141406_rolify_create_roles.rb,在最后加上[5.1]這個參數,前面20171217141406這個時間戳與你的不一樣。

class RolifyCreateRoles < ActiveRecord::Migration[5.1]

  

 18、在終端下輸入以下代碼:

$ rails db:migrate

  

19、打開app/controllers/application_controller.rb,輸入以下代碼:

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
      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

  注:以上代碼是設置第一個注冊用戶id=1時為admin管理員,當id=2時就不是admin,當我注冊第一個用戶后我就把1改成2,admin改成user,那注第2個賬號時就是user權限 ,待會user做一個比admin還低一級的權限。

 

20、打開app/models/ability.rb,輸入以下代碼:

class Ability
  include CanCan::Ability
  def initialize(user)
        if user.has_role? :admin  #這里的admin權限等級最高,能增刪改查。
          can :manage, :all
        elsif user.has_role? :user  #這里的user權限等級次於admin,能增改查,沒有刪除功能。
          can :manage, :all
          cannot :destroy, :all  #這里就是去掉刪除功能。
        else
          can :read, :all    #else之后的用戶只有只讀功能。
        end
  end
end

注:上面圖片內容截圖於http://blog.xdite.net/posts/2012/07/30/cancan-rule-engine-authorization-based-library-3/

 

21、打開app/controllers/lists_controller.rb,增加以下代碼:

class ListsController < ApplicationController
  load_and_authorize_resource  #這個是cancancan全局權限驗證的方法
  before_action :authenticate_user!  #這個是devise的登錄驗證方法

  注:這里有 load_and_authorize_resource 

 

22、打開app/controllers/application_controller.rb,增加以下代碼:

rescue_from CanCan::AccessDenied do |exception|
    redirect_to lists_path , :alert => exception.message
    exception.action, exception.subject
end

  注:如果權限認證失敗,cancan會拋出一個CanCan::AccessDenied的異常,你可以在ApplicationController中捕獲它來顯示自己內容。這里引用了https://www.cnblogs.com/bendanchenzhicheng/archive/2011/09/05/2167451.html

 

23、打開app/views/layouts/application.html.erb,增加以下代碼:

<!DOCTYPE html>
<html>
  <head>
    <title>Demo</title>
    <%= csrf_meta_tags %>

    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <div class="container">
        <div class="col-md-12">
    <%= link_to '首頁', root_path %> |
    <% if current_user %>
      Welcome come <%= current_user.email %>
      <%= 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 %>
    <p class="text-danger"><%= alert %></p>
    <%= yield %>
  </div>
</div>
  </body>
</html>

  

23、打開 app/views/home/index.html.erb,增加以下代碼:

<h1>Home#index</h1>
<p>Find me in app/views/home/index.html.erb</p>
  <% if user_signed_in? %>
          <%= link_to "Lists", lists_path %>
  <% end %>

  

24、打開app/views/lists/index.html.erb,增加以下代碼:

<h1>Lists</h1>
  <table class="table table-bordered">
    <tr>
      <th>Name</th>
      <th>Idcard</th>
      <th>Phone</th>
      <% if can? :manage, @list %>
      <th colspan="3"></th>
      <% end %>
    </tr>
      <% @lists.each do |list| %>
    <tr>
      <td><%= list.name %></td>
      <td><%= list.idcard %></td>
      <td><%= list.phone %></td>
      <% if can? :manage, @list %>
      <td><%= link_to 'Show', list %></td>
      <td><%= link_to 'Edit', edit_list_path(list) %></td>
      <% if can? :destroy, @list %>
      <td><%= link_to 'Destroy', list, method: :delete, data: { confirm: 'Are you sure?' } %></td>
      <% end %>
      <% end %>
    </tr>
    <% end %>
  </table>
<% if can? :create, @list %>
<%= link_to 'New List', new_list_path %>
<% end %>

  

25、按以上的操作基本實現了三角色權限管理,現在我們打開終端,在項目內,輸入rails s,啟動服務器,打開瀏覽器,輸入http://localhost:3000,就正常顯示一個Log in的頁面。現在我們注冊一個具有admin權限的賬號;成功后,到回第19項操作,把1改成2,把admin改成user,保存,我們再注冊一個具有user權限的賬號,注冊成功后,馬上到回第19項操作,注釋掉以下代碼:

  # def after_sign_in_path_for(resource)
  #       if resource.is_a?(User)
  #         if User.count == 2
  #           resource.add_role 'user'
  #         end
  #         resource
  #       end
  #       root_path
  #   end

  

 

好了,我們現在有2個賬號,一個是admin的,一個是user的。然后把上面這個功能注釋后,以后注冊的都是只有read功能的賬號。

ok,完成。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM