Handling exception gem Cancancan Rails
Bài đăng này đã không được cập nhật trong 7 năm
Chào các bạn, việc phân quyền người dùng khi bạn tạo ra một ứng dụng là việc quan trọng và không thể thiếu. Với Rails việc này trở nên dễ dàng khi bạn sử dụng gem "Cancancan" để xử lý. Sử dụng là một chuyện nhưng để handle được những exception mà nó sinh ra lại không phải dễ dàng. Trong bài viết này mình sẽ đưa ra một số cách để handle exception của gem Cancancan, sau đây mình sẽ đi và chi tiết.
- Ngoại lệ CanCan::AccessDenied sẽ được raise ra khi gọi method authorize! trong controller action (hoặc sử dụng load_and_authorize_resource cho tất cả các controller action) mà User không được phép thực hiện action đã cho. Một thông điệp sẽ sinh ra:
Cách 1: Xử lý trực tiếp trong action
authorize! :read, Article, message: "Unable to read this article."
Hoặc:
raise CanCan::AccessDenied.new("Not authorized!", :read, Article)
Bạn có thể định nghĩa trong file config/locales/en.yml để custom thông điệp này:
en:
unauthorized:
manage:
all: "Not authorized to %{action} %{subject}."
user: "Not allowed to manage other user accounts."
update:
project: "Not allowed to update this project."
Trong đó: action bao gồm: read, manage, create, update,... subject: all, object,...
Cách 2: Bắt ngoại lệ và sửa đổi hành vi của nó trong ApplicationController
- Hiển thị ra 1 thông báo và chuyển về Home page:
class ApplicationController < ActionController::Base
rescue_from CanCan::AccessDenied do |exception|
respond_to do |format|
format.json { head :forbidden }
format.html { redirect_to main_app.root_url, alert: exception.message }
end
end
end
- Hoặc bạn có thể tạo ra file public/403.html và render khi có ngoại lệ:
class ApplicationController < ActionController::Base
rescue_from CanCan::AccessDenied do |exception|
render file: "#{Rails.root}/public/403.html", status: 403, layout: false
end
end
Cách 3: Custom lại trang mà bạn muốn chuyển tới cho từng User
Ở đây mình đưa ra cách giải quyết mà mình đã từng làm để chuyển về trang theo từng loại User đã được phân quyền khi có ngoại lệ. Giả sử mình có: Admin - quản trị, User - người dùng thông thường của ứng dụng
- Với quyền là Admin, khi gặp exception mình sẽ chuyển về root của admin (admin_root_url)
- Với quyền là User, khi gặp exception mình sẽ huyển về root của user (root_url)
Mình xử lý như sau:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
rescue_from Exception do |exception|
flash[:warning] = exception.message
redirect_to_root
end
rescue_from ActiveRecord::RecordNotFound do |exception|
flash[:warning] = exception.message
redirect_to root_url
end
private
def redirect_to_root
(current_admin_user && namespace == "admin") ?
redirect_to(admin_root_url) : redirect_to(root_url)
end
end
Bạn hãy custom lại và handling exception theo cách mà bạn muốn ^_^
Trong bài viết này mình đã đưa ra 1 số cách handing exception khi sử dụng gem Cancancan để phân quyền cho người dùng. Bạn hãy lựa chọn cho ứng dụng của mình 1 cách hợp lý hay có thể đưa ra cách giải quyết tốt hơn. Rất mong nhận được sự dóng góp của các bạn!! Good luck! Link tài liệu tham khảo: https://github.com/CanCanCommunity/cancancan/wiki/exception-handling
All rights reserved
Bình luận