我無法允許未註冊/未登錄的用戶查看索引並顯示博客部分的頁面。我正在使用Pundit進行授權,並意識到目前我的政策設置爲不允許非用戶查看博客部分的任何部分,但我不知道如何解決該問題,以便對索引沒有政策並且顯示頁面。允許非註冊用戶查看具有評論者的內容
我的目標是具備以下條件:
允許管理員和編輯器來查看,創建,編輯和刪除博客
這部分工作pefect
允許註冊用戶查看博客
這部分工作完美
允許非註冊/非登錄用戶查看博客
這部分不工作
當我嘗試查看索引頁面一個未註冊/未登錄的用戶,我將得到一個訪問被拒絕的閃存消息,它出自我的應用程序控制器,它正在執行當前策略下應該執行的操作。
所以我的問題是:如何修改我的策略以允許非註冊/未登錄的用戶只查看索引和顯示頁面?
應用控制器
class ApplicationController < ActionController::Base
include Pundit
rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
before_filter :configure_permitted_parameters, if: :devise_controller?
private
def user_not_authorized(exception)
flash[:danger] = "Access denied. You are not authorized to view that page."
redirect_to (request.referrer || root_path)
end
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up) { |u| u.permit(:username, :email, :password, :password_confirmation, :remember_me) }
devise_parameter_sanitizer.permit(:sign_in) { |u| u.permit(:username, :email, :password, :remember_me) }
devise_parameter_sanitizer.permit(:account_update) {|u| u.permit(:username, :email, :password, :password_confirmation, :current_password)}
end
end
應用策略
class ApplicationPolicy
attr_reader :user, :record
def initialize(user, record)
raise Pundit::NotAuthorizedError, "You must be logged in to perform this action" unless user
@user = user
@record = record
end
def index?
true
end
def show?
scope.where(:id => record.id).exists?
end
def create?
false
end
def new?
create?
end
def update?
false
end
def edit?
update?
end
def destroy?
false
end
def scope
Pundit.policy_scope!(user, record.class)
end
class Scope
attr_reader :user, :scope
def initialize(user, scope)
@user = user
@scope = scope
end
def resolve
scope
end
end
end
郵政政策
class PostPolicy < ApplicationPolicy
attr_reader :post
class Scope < Scope
def resolve
if user&.admin?&.editor?&.user?
scope.all
else user != admin? || editor? || user?
scope
end
end
end
def permitted_attributes
if user.admin? || user.editor?
[:title, :body, :image, :permalink, :description, :tag_list, :username]
else
[:title, :body, :image, :username]
end
end
def index?
true
end
def show?
true
end
def new?
user.admin? || user.editor?
end
def create?
user.admin? || user.editor?
end
def update?
user.admin? || user.editor?
end
def destroy?
user.admin? || user.editor?
end
end
柱控制器
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
after_action :verify_authorized, only: [:destroy]
def index
@meta_title = "Blog"
@meta_description = "page description here"
@posts = Post.all.order("created_at DESC").paginate(:page => params[:page], :per_page => 4)
end
def show
@meta_title = @post.title
@meta_description = @post.description
end
def new
@meta_title = "Add New Blog"
@meta_description ="Add a new blog."
@post = Post.new
authorize @post
end
def edit
@meta_title = "Edit Blog"
@meta_description ="Edit an existing blog."
authorize @post
end
def create
@post = Post.new
@post.update_attributes(permitted_attributes(@post))
@post.user = current_user if user_signed_in?
authorize @post
if @post.save
redirect_to @post, notice: 'Post was successfully created.'
else
render :new
end
end
def update
@post = Post.find(params[:id])
if @post.update_attributes(permitted_attributes(@post))
authorize @post
redirect_to @post, notice: 'Post was successfully updated.'
else
render :edit
end
end
def destroy
if @post.present?
@post.destroy
authorize @post
else
skip_authorization
end
redirect_to posts_url, notice: 'Post was successfully deleted.'
end
private
# Use callbacks to share common setup or constraints between actions.
def set_post
@post = Post.find(params[:id])
end
# Only allow the white list through.
def post_params
params.require(:post).permit(policy(@post).permitted_attributes)
end
end
我已經看到了類似的問題問Pundit policy_scoper error,但解決方案建議似乎並沒有在我的情況下工作。
它看起來應該不會從索引觸發您的策略或顯示操作,因爲您在任一操作中都沒有調用「授權」。如果您將「授權Post」添加到您的索引操作會發生什麼?我會想,因爲你在PostPolicy.index中返回true?它應該工作。 – Scott
Hi @scott我試了和。 已無效,<@post>創建了錯誤。您可以在控制器中看到<@post>適用於索引中的所有其他操作。 –
Nate
@Scott你有任何其他想法或見解?我仍然努力克服這個問題。我已經嘗試了一切,從索引中的skip_authorization添加到刪除索引,並顯示def超出了發佈的策略,然後是帖子和應用程序策略。無論如何,當以未登錄/訪客用戶的身份訪問時,仍然會收到「未經授權」的閃存消息。 – Nate