Handling exception gem Cancancan Rails
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 ...
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