这是我在食谱展示页面上看到的:

我的控制器看起来像这样:
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我的policy.rb:
class RecipePolicy < ApplicationPolicy
class Scope < Scope
def resolve
scope.all
end
def index?
false
end
def show?
false
end
end
end这是在向show操作添加'authorize @recipe‘时出现的错误消息:

我需要为每个食谱,但不是食谱显示行动本身的评论专家授权。我做错了什么?谢谢你的帮助!!
发布于 2021-02-19 18:26:04
authenticate_user! (您还没有向我们展示/解释过它,但可能是devise中的一种方法或类似方法?)可能与登录有关--那是身份验证,而不是授权,因此超出了Pundit试图解决的范围。
身份验证就是检查“你登录了吗?”如果此检查失败,则服务器将使用401 status进行响应。
授权就是检查“您是否被允许执行此操作(可能是作为来宾)?”如果此检查失败,则服务器将以403 status响应
现在,您可能还在应用程序中添加了一些代码,如下所示:
class ApplicationController < ActionController::Base
include Pundit
after_action :verify_authorized, except: :index # !!!!!
end这个after_action检查是一个安全网;它确保您永远不会忘记授权一个端点--因为默认情况下,这将允许任何用户执行该操作!此检查的存在是导致上述错误的原因。
所以。解释完这一点后,让我们看看如何实现它。
RecipesController#show guests访问,或仅可由登录的访问如果且仅当答案是"guests“,则添加以下内容:
skip_before_action :authenticate_user!, only: :showrecipe。你如何实现它呢?选项1(推荐):
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选项2(同样有效,但更糟糕的是,因为它意味着您不能依赖策略类的单元测试):
class RecipesController < ApplicationController
def show
skip_authorization # !!!
@recipe = Recipe.find(params[:id])
# ...
end
endhttps://stackoverflow.com/questions/66275290
复制相似问题