ApplicationController 未挽救 Pundit 未授权错误
ApplicationController not rescuing Pundit Not Authorized Error
我正在使用 Rails 5.2、Pundit 1.1 和 rails_admin 1.2
我的 application_controller.rb 中有以下内容:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
include Pundit
rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
private
def user_not_authorized(exception)
flash[:alert] = "You are not authorized to perform this action."
redirect_to root_path
end
end
我的 application.policy.rb 中有以下内容:
class ApplicationPolicy
.
.
.
def rails_admin?(action)
case action
when :dashboard
user.admin?
when :index
user.admin?
when :show
user.admin?
when :new
user.admin?
when :edit
user.admin?
when :destroy
user.admin?
when :export
user.admin?
when :history
user.admin?
when :show_in_app
user.admin?
else
raise ::Pundit::NotDefinedError, "unable to find policy #{action} for #{record}."
end
end
end
在我的 config/initializers/rails_admin.rb 中,我有以下内容:
RailsAdmin.config do |config|
### Popular gems integration
## == Devise ==
config.authenticate_with do
warden.authenticate! scope: :user
end
config.current_user_method(&:current_user)
## == Pundit ==
config.authorize_with :pundit
end
module RailsAdmin
module Extensions
module Pundit
class AuthorizationAdapter
def authorize(action, abstract_model = nil, model_object = nil)
record = model_object || abstract_model && abstract_model.model
if action && !policy(record).send(*action_for_pundit(action))
raise ::Pundit::NotAuthorizedError.new("not allowed to #{action} this #{record}")
end
@controller.instance_variable_set(:@_pundit_policy_authorized, true)
end
def authorized?(action, abstract_model = nil, model_object = nil)
record = model_object || abstract_model && abstract_model.model
policy(record).send(*action_for_pundit(action)) if action
end
def action_for_pundit(action)
[:rails_admin?, action]
end
end
end
end
end
如果用户是管理员,则他们可以访问管理仪表板。
但是,如果用户不是管理员,则应使用即显消息将他们重定向到主页。
当我尝试访问 non-admin 用户的 Rails 管理仪表板时,我得到以下信息:
为什么 ApplicationController 没有拯救 Pundit::NotAuthorizedError?
我创建了一个重现此错误的示例应用程序:https://github.com/helphop/sampleapp
编辑:更新 —
您实际遇到的错误涉及 RailsAdmin 内部的路径帮助程序——例如 root_url
或 root_path
。当rescue_from
遇到错误时,它会自行转义。
话虽如此,更改 redirect_to "/"
应该可以解决问题。
您应该在 config.authorize_with :pundit
之前添加 config.parent_controller = 'ApplicationController'
。它会说 Rails Admin 从您的 ApplicationController 继承的 RailsAdmin::ApplicationController 和 rescue 将起作用。
希望对您有所帮助。
我正在使用 Rails 5.2、Pundit 1.1 和 rails_admin 1.2
我的 application_controller.rb 中有以下内容:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
include Pundit
rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
private
def user_not_authorized(exception)
flash[:alert] = "You are not authorized to perform this action."
redirect_to root_path
end
end
我的 application.policy.rb 中有以下内容:
class ApplicationPolicy
.
.
.
def rails_admin?(action)
case action
when :dashboard
user.admin?
when :index
user.admin?
when :show
user.admin?
when :new
user.admin?
when :edit
user.admin?
when :destroy
user.admin?
when :export
user.admin?
when :history
user.admin?
when :show_in_app
user.admin?
else
raise ::Pundit::NotDefinedError, "unable to find policy #{action} for #{record}."
end
end
end
在我的 config/initializers/rails_admin.rb 中,我有以下内容:
RailsAdmin.config do |config|
### Popular gems integration
## == Devise ==
config.authenticate_with do
warden.authenticate! scope: :user
end
config.current_user_method(&:current_user)
## == Pundit ==
config.authorize_with :pundit
end
module RailsAdmin
module Extensions
module Pundit
class AuthorizationAdapter
def authorize(action, abstract_model = nil, model_object = nil)
record = model_object || abstract_model && abstract_model.model
if action && !policy(record).send(*action_for_pundit(action))
raise ::Pundit::NotAuthorizedError.new("not allowed to #{action} this #{record}")
end
@controller.instance_variable_set(:@_pundit_policy_authorized, true)
end
def authorized?(action, abstract_model = nil, model_object = nil)
record = model_object || abstract_model && abstract_model.model
policy(record).send(*action_for_pundit(action)) if action
end
def action_for_pundit(action)
[:rails_admin?, action]
end
end
end
end
end
如果用户是管理员,则他们可以访问管理仪表板。 但是,如果用户不是管理员,则应使用即显消息将他们重定向到主页。
当我尝试访问 non-admin 用户的 Rails 管理仪表板时,我得到以下信息:
我创建了一个重现此错误的示例应用程序:https://github.com/helphop/sampleapp
编辑:更新 —
您实际遇到的错误涉及 RailsAdmin 内部的路径帮助程序——例如 root_url
或 root_path
。当rescue_from
遇到错误时,它会自行转义。
话虽如此,更改 redirect_to "/"
应该可以解决问题。
您应该在 config.authorize_with :pundit
之前添加 config.parent_controller = 'ApplicationController'
。它会说 Rails Admin 从您的 ApplicationController 继承的 RailsAdmin::ApplicationController 和 rescue 将起作用。
希望对您有所帮助。