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 đó.