Giới thiệu cách sử dụng gem cancancan, rolify

Gem cancancan là một gem dùng để phân quyền trong ruby, giúp cho việc phân chia các quyền của user và admin dễ dàng hơn. Và Rolify là một gem hỗ trợ cho Cancancan trong sự phân quyền đó.

Cancancan hạn chế các quyền, tài nguyên mà một user có thể truy cập.

Sau đây mình xin hướng dẫn các bạn các bước cơ bản để sử dụng gem cancancan, rolify

I. Gem cancancan

  1. Cài đặt.
gem "cancancan", "~> 2.0"
# chạy lệnh "bundle install".
  • Quyền của người dùng được định nghĩa trong lớp Ability. Để tạo ra ability.rb bạn cần chạy lệnh "rails g cancan:ability". Hệ thống sẽ tạo ra file abillity.rb cho chúng ta khai báo quyền cho user.
class Ability
  include CanCan::Ability
  
  def initialize user
     user ||= User.new # nếu chưa login
     if user.is_admin?
         can :manage, :all # cấp tất cả quyền cho admin
     else
         can [:index, :show], Document # cấp quyền cho user không phải là admin
     end
  end
end
  • Phương thức can ở đây bao gồm hai tham số truyền vào là action mà bạn muốn cài đặt phân quyền và tên class đối tượng. Hai tham số này bạn có thể nhập theo kiểu mảng.
  1. Sử dụng.

2.1. Kiểm tra Ability

  • Để kiếm tra quyền của user hiện tại ở view hoặc controller chúng ta sử dụng can? hoặc cannot?
<% if can? :update, @document %>
    <%= link_to "Edit", edit_article_path(@document) %>
<% end %>

2.2. Authorizations

  • Để cho phép một ngoại lệ nếu user không có quyền sử dụng hành động đó. chúng ta sử dụng authorize!
  • Cụ thể là method dưới đây sẽ tạo ra một ngoại lệ cho người dùng hiện tại nếu họ không có quyền xem tài liệu.
def show
  @document = Article.find(params[:id])
  authorize! :read, @document
end

2.3. Loaders

  • Chẳng lẽ mỗi hành động chúng ta phải sử dụng can? cannot?. Thiết lập này thật mệt mỏi. do đó gem cancancan cung cấp phương thức load_and_authorize_resource để tự động phân quyền cho tất cả các action trong controler.
class DocumentsController < ApplicationController
  load_and_authorize_resource
end
  • Điều này cũng giống như gọi load_resource và authorize_resource bởi vì chúng là hai bước riêng biệt và nên sử dụng authorize_resource thay vì load_and_authorize_resource. Để tránh lỗi không load được tài nguyên.

2.4. Lock It Down

  • Nếu bạn muốn đảm bảo việc kiểm tra quyền đối với mọi hành động trong controller của bạn, hãy thêm check_authorization vào ApplicationController.
class ApplicationController < ActionController::Base
  check_authorization
end
  • Nếu bạn muốn bỏ qua việc check_authorization trên một controller nào đó thì khai báo skip_authorization_check vào controller đó.

II. Gem rolify.

  1. Cài đặt.
gem "rolify"
# chạy lệnh "bundle install".
  • chạy lệnh "rails g rolify Role User". Hệ thống tạo ra cho chúng ta file migration create Role.
class RolifyCreateRoles < ActiveRecord::Migration[5.1]
  def change
    create_table(:roles) do |t|
      t.string :name
      t.references :resource, :polymorphic => true

      t.timestamps
    end

    create_table(:users_roles, :id => false) do |t|
      t.references :user
      t.references :role
    end
    
    add_index(:roles, :name)
    add_index(:roles, [ :name, :resource_type, :resource_id ])
    add_index(:users_roles, [ :user_id, :role_id ])
  end
end

Model role.rb

class Role < ApplicationRecord
    has_and_belongs_to_many :users, :join_table => :users_roles

    belongs_to :resource,
               :polymorphic => true,
               :optional => true

    validates :resource_type,
              :inclusion => { :in => Rolify.resource_types },
              :allow_nil => true

    scopify
end
  1. Sử dụng.

2.1. Khai báo

#Model user.rb
class User < ApplicationRecord
   rolify
end

2.2. Kết hợp cancancan.

  • Sử dụng trong ability.
if user.has_role? :admin
    can :manage, :all
else
    can [:index, :show], Document
end

2.2. Một số method trong rolify

  • Thêm role cho user
user = User.find(1)
user.add_role :admin
  • Xoá role user
user = User.find(3)
user.remove_role :admin

Mong rằng bài viết này có thể giúp bạn sử dụng Cancancan nhanh hơn trong quá trình kiểm tra quyền!

Cảm ơn đã dành thời gian cho bài viết của mình. Tham khảo: Cancancan Rolify