12/08/2018, 13:06

Gem cancancan

**Cài đặt: ** Trong Rails 3 và 4, để cài đặt ta thêm dòng sau vào Gemfile sau đó bundle install. gem 'cancancan' , '~> 1.10' Giới thiệu Gem cancancan là một gem dễ sử dụng hỗ trợ việc phân quyền cho người dùng. I. Định nghĩa Abilities Các quyền hạn của user được định ...

**Cài đặt: **

  • Trong Rails 3 và 4, để cài đặt ta thêm dòng sau vào Gemfile sau đó bundle install.
gem 'cancancan', '~> 1.10'

Giới thiệu

Gem cancancan là một gem dễ sử dụng hỗ trợ việc phân quyền cho người dùng.

I. Định nghĩa Abilities

Các quyền hạn của user được định nghĩa trong class Ability. Để tạo file ability.rb ta chạy lệnh sau trong command:

rails g cancan:ability

Lệnh này tự động tạo ra file app/models/ability.rb với nội dung:

class Ability
  include CanCan::Ability

  def initialize(user)
  end
end

** II. Kiểm tra Abilities & Authorization**

Để kiểm tra quyền hiện tại của user ta sử dụng lệnh can? và cannot? cả trên view và controller.

<% if can? :update, @article %>
  <%= link_to "Edit", edit_article_path(@article) %>
<% end %>

Phương thức authorize! trong controller để kiểm tra quyền và trả về lỗi nếu quyền đó là không được phép hoặc chưa được khai báo.

def show
  @article = Article.find(params[:id])
  authorize! :read, @article
end

Thiết lập điều này cho mỗi hành động có thể gây lặp nhàm chán, do đó gem cancancan cung cấp phương thức load_and_authorize_resource để tự động phân quyền trong tất cả các controler.

class ArticlesController < ApplicationController
  load_and_authorize_resource

  def show
    # @article is already loaded and authorized
  end
end

Strong Parameters

Khi sử dụng strong_parameters or Rails 4+, bạn phải dọn đầu vào trước khi lưu bản ghi, trong hành động như :create và :update.

Đối với hành động :update, cancan sẽ xác thực và phân quyền tài nguyên nhưng không thay đổi chúng tự động, giống như:

def update
  if @article.update_attributes(update_params)
    # hurray
  else
    render :edit
  end
end
...

def update_params
  params.require(:article).permit(:body)
end

Đối với hành động :create, Cancan sẽ thử khởi tạo đầu vào bằng cách xem xét nếu controller sẽ phản hồi bằng các lệnh sau:

1.create_params

2.<model_name>_params

3.resource_params

Ngoài ra, load_and_authorize_resource có thể gọi một param_method tùy ý được xác định trong controller:

class ArticlesController < ApplicationController
  load_and_authorize_resource param_method: :my_sanitizer

  def create
    if @article.save
      # hurray
    else
      render :new
    end
  end

  private

  def my_sanitizer
    params.require(:article).permit(:name)
  end
end

Ta cũng có thể dùng một string mà trong controller sử dụng instance_eval và cần đúng chuẩn ruby:

load_and_authorize_resource param_method: 'permitted_params.article'

Cuối cùng, load_and_authorize_resource có khả năng liên kết param_method với một object Proc được gọi trong controller như một đối số duy nhất:

load_and_authorize_resource param_method: Proc.new { |c| c.params.require(:article).permit(:name) }

III. Xử lý các trường hợp không hợp lệ

Đối với các hành động không hợp lệ cuả user, một CanCan: : AccessDenied được sinh ra. Cancan hỗ trợ nguời dùng có thể thay đổi trang chuyển tiếp hoặc thông báo lỗi trong ApplicationController:

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

IV. Lock It Down

Nếu muốn chắc chắn việc phân quyền được áp dụng trong mọi hành động, ta thêm check_authorization vào ApplicationController:

class ApplicationController < ActionController::Base
  check_authorization
end

Điều này sẽ sinh ra việc không muốn phân quyền trong một số hành động. Nếu bạn muốn bỏ qua việc kiểm tra quyền này trong một controller, thêm phương thức skip_authorization_check vào controller đó.

0