Ruby on rails Pundit::AuthorizationNotPerformedError
这是我在菜谱展示页面上看到的内容: 我的控制器看起来像:Ruby on rails Pundit::AuthorizationNotPerformedError,ruby-on-rails,ruby,rubygems,pundit,Ruby On Rails,Ruby,Rubygems,Pundit,这是我在菜谱展示页面上看到的内容: 我的控制器看起来像: class RecipesController < ApplicationController skip_before_action :authenticate_user!, only: [:index, :show] def index if params[:query].present? @recipes = policy_scope(Recipe).search_by_title_and_desc
class RecipesController < ApplicationController
skip_before_action :authenticate_user!, only: [:index, :show]
def index
if params[:query].present?
@recipes = policy_scope(Recipe).search_by_title_and_description(params[:query]).order(created_at: :desc)
else
@recipes = policy_scope(Recipe).order(created_at: :desc)
end
end
def show
@recipe = Recipe.find(params[:id])
@recipes = Recipe.first(5)
end
end
class RecipesController
My policy.rb:
class RecipePolicy < ApplicationPolicy
class Scope < Scope
def resolve
scope.all
end
def index?
false
end
def show?
false
end
end
end
类RecipePolicy
这是向show action添加“authorize@recipe”时的错误消息:
我需要权威人士对每个菜谱的评论进行授权,但不需要对菜谱表演本身进行授权。我做错了什么?谢谢你的帮助
验证用户身份
(您尚未向我们展示/解释,但可能是来自或类似的方法?)可能与登录有关——这是身份验证,而不是授权,因此超出了权威人士试图解决的范围
身份验证就是检查“您是否已登录?”。如果此检查失败,则服务器将以一个错误响应
授权是关于检查“是否允许您执行此操作(可能作为来宾)?”。如果此检查失败,则服务器将以
现在,您可能已经在应用程序中添加了如下代码:
class ApplicationController < ActionController::Base
include Pundit
after_action :verify_authorized, except: :index # !!!!!
end
假设您已经执行了任何必要的身份验证,您希望让任何用户看到任何配方
。你如何实现这一点
备选案文1(建议):
类RecipePolicy
选项2(也可以,但更糟糕的做法是,这意味着您不能依赖策略类的单元测试):
class RecipesController
验证用户身份
(您尚未向我们展示/解释,但可能是来自或类似的方法?)可能与登录有关——这是身份验证,而不是授权,因此超出了权威人士试图解决的范围
身份验证就是检查“您是否已登录?”。如果此检查失败,则服务器将以一个错误响应
授权是关于检查“是否允许您执行此操作(可能作为来宾)?”。如果此检查失败,则服务器将以
现在,您可能已经在应用程序中添加了如下代码:
class ApplicationController < ActionController::Base
include Pundit
after_action :verify_authorized, except: :index # !!!!!
end
假设您已经执行了任何必要的身份验证,您希望让任何用户看到任何配方
。你如何实现这一点
备选案文1(建议):
类RecipePolicy
选项2(也可以,但更糟糕的做法是,这意味着您不能依赖策略类的单元测试):
class RecipesController
您的show?
方法具有false
硬编码。因此,任何情况下都不允许用户查看任何配方。我建议阅读权威文档。这里有一些很好的例子。@spickermann它是通过写-def show在policy.rb中硬编码的吗?false end-?是,当show?
方法返回false
时,表示当前用户无权查看当前配方。您需要将false
替换为在应用程序上下文中有意义的代码,并且仅当当前用户被允许查看特定配方时才返回true
。show?
方法具有false
硬编码。因此,任何情况下都不允许用户查看任何配方。我建议阅读权威文档。这里有一些很好的例子。@spickermann它是通过写-def show在policy.rb中硬编码的吗?false end-?是,当show?
方法返回false
时,表示当前用户无权查看当前配方。您需要将false
替换为在应用程序上下文中有意义的代码,并在允许当前用户查看特定配方时返回true
(仅限)。非常感谢您的回答!!我尝试了两种选择,但只有选择2起作用。可能是因为我有“操作前:验证用户!”在我的应用程序控制器中?我真的很感谢你的解释,再次感谢@Witta你注意到“警告!!注意到范围
类在这里结束!!!”?您最初的策略没有按照您认为的那样执行,因为您在错误的类中定义了方法。正如我在帖子中所说的,身份验证和授权是不同的事情。他们是独立的。别把它们弄混了。非常感谢你的回答!!我尝试了两种选择,但只有选择2起作用。也许是因为我有“行动前”
class RecipePolicy < ApplicationPolicy
class Scope < Scope
def resolve
scope.all
end
end ## WARNING!! NOTICE THAT THE `Scope` CLASS ENDS HERE!!!
def show?
true # !!!!
end
end
class RecipesController < ApplicationController
# ...
def show
@recipe = Recipe.find(params[:id])
authorize(@recipe) # !!!
# ...
end
end
class RecipesController < ApplicationController
def show
skip_authorization # !!!
@recipe = Recipe.find(params[:id])
# ...
end
end