Gem cancancan
Bài đăng này đã không được cập nhật trong 8 năm
**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 đó.
Tài liệu tham khảo: https://github.com/CanCanCommunity/cancancan
All rights reserved