Tìm hiểu về gem Cancancan trong Rails
Bài đăng này đã không được cập nhật trong 4 năm
1. Gem cancancan là gì?
- Gem cancancan là một thư viện phân quyền trong ruby và ruby on rails, nó hạn chế những tài nguyên mà một người dùng nhất định được phép truy cập.
- Tất cả các quyền được xác định trong một hoặc nhiều file ability và không bị trùng lặp trên controllers, views, và truy vấn database.
- Giúp dễ bảo trì và kiểm tra việc phân quyền logic.
2. Các chức năng chính
Bao gồm 2 chức năng chính:
- Thư viện authorizations cho phép định nghĩa các quy tắc để truy cập các đối tượng khác nhau và cung cấp helpers để kiểm tra các quyền đó.
- Rails helpers để đơn giản hóa code trong controllers bằng cách thực hiện việc tải và kiểm tra quyền của các models một cách tự động và giảm mã trùng lặp.
3. Cài đặt
Thêm vào Gemfile:
gem "cancancan"
Sau đó chạy lệnh sau:
bundle install
4. Định nghĩa Abilities
User permissions được xác định trong class Ability.
Tạo class Ability trong app/models/ability.rb bằng lệnh sau:
rails g cancan:ability
Ví dụ về các quy tắc để đọc một model Post:
class Ability
include CanCan::Ability
def initialize(user)
can :read, Post, public: true
if user.present? # additional permissions for logged in users (they can read their own posts)
can :read, Post, user_id: user.id
if user.admin? # additional permissions for administrators
can :read, Post
end
end
end
end
TÌm hiểu thêm về Defining Abilities.
5. Can? và cannot?
- Hai method can? và cannot? dùng để kiểm tra quyền của người dùng hiện tại. Ta sử dụng 2 method này trong views hoặc controllers. Ví dụ:
<% if can? :read, @post %>
<%= link_to "View", @post %>
<% end %>
Tìm hiểu thêm về checking abilities.
6. Fetching records - tìm nạp bản ghi
- Cancancan có khả năng truy xuất tất cả các đối tượng mà người dùng được phép truy cập
Post.accessible_by(current_ability)
-> Sẽ sử dụng các quy tắc của bạn để đảm bảo rằng người dùng chỉ truy xuất danh sách các bài Post có thể đọc được.
Tìm hiểu thêm về Fetching records.
7. Controller helpers
7.1 Authorizations
- Cancancan cung cấp cho rails phương thức
authorize!
trong controller sẽ đưa ra một ngoại lệ nếu user không thể thực hiện được action đã cho. - Ví dụ:
def show
@post = Post.find(params[:id])
authorize! :read, @post
end
7.2 Loaders
- Method load_and_authorize_resource được cung cấp để tự động cho phép tất cả các actions trong resource controllers kiểu RESTful (thiết lập nó cho các action lẻ tẻ).
- Ví dụ:
class PostsController < ApplicationController
load_and_authorize_resource
def show
# @post is already loaded and authorized
end
def index
# @posts is already loaded with all posts the user is authorized to read
end
end
Tìm hiểu thêm về Authorizing Controllers Action.
7.3 Strong parameters
- Bạn phải làm sạch đầu vào trước khi lưu bản ghi, trong các actions như :create và :update
- Đối với action :update, cancancan sẽ tải và cấp quyền cho resource nhưng không tự động thay đổi nó, vì vậy cách sử dụng thông thường như sau:
def update
if @post.update post_params
# hurray
else
render :edit
end
end
...
def post_params
params.require(:post).permit(:body)
end
- Với action :create, cancancan sẽ cố gắng khởi tạo một instance mới với đầu vào được làm sạch bằng cách tìm xem controller của bạn có các phương thức sau hay không (theo thứ tự):
create_params
<model name>_params
(quy ước mặc định trong rails để đặt tên cho method params của bạn).resource_params
(phương pháp đặt tên chung trong mỗi controller).
Ngoài ra, nếu bạn muốn sử dụng một method tùy chỉnh khác để làm sạch đầu vào, bạn có thể sử dụng
load_and_authorize_resource
với tùy chọnparam_method
để chỉ định.
class PostsController < ApplicationController
load_and_authorize_resource param_method: :my_sanitizer
def create
if @post.save
# hurray
else
render :new
end
end
private
def my_sanitizer
params.require(:post).permit(:name)
end
end
- Bạn cũng có thể sử dụng chuỗi sẽ được đánh giá trong ngữ cảnh của controller bằng cách sử dụng
instance_eval
và phải chứa code ruby hợp lệ.
load_and_authorize_resource param_method: 'permitted_params.post'
- Cuối cùng, bạn cũng có thể liên kết
param_method
với đối tượng Proc sẽ được gọi với controller như một đối số duy nhất.
load_and_authorize_resource param_method: Proc.new { |c| c.params.require(:post).permit(:name) }
Tìm hiểu thêm về strong parameters.
8. Xử lý truy cập trái phép
- Nếu cấp quyền cho người dùng không thành công, ngoại lệ CanCan::AccessDenied sẽ được bắn ra. Bạn có thể nắm bắt và sửa đổi hành vi của nó trong controller như ví dụ sau:
class ApplicationController < ActionController::Base
rescue_from CanCan::AccessDenied do |exception|
respond_to do |format|
format.json { head :forbidden, content_type: 'text/html' }
format.html { redirect_to main_app.root_url, notice: exception.message }
format.js { head :forbidden, content_type: 'text/html' }
end
end
end
9. Lock it down
- Nếu bạn muốn đảm bảo phân quyền xảy ra trên mọi action trong ứng dụng của mình, hãy thêm check_authorization vào ApplicationController.
class ApplicationController < ActionController::Base
check_authorization
end
Nó sẽ đưa ra một ngoại lê nếu phân quyền không xảy ra trong một action, để bỏ qua phân quyền trong một controller cụ thể, hãy thêm method skip_authorization_check
vào trong controller đó.
TÌm hiểu thêm về Ensure Authorizations.
Cảm ơn các bạn đã theo dõi. Nguồn bài viết: wiki cancancan in rails.
All rights reserved