【问题标题】:Authorization settings using pundit gem rails使用 pundit gem rails 的授权设置
【发布时间】:2016-11-15 15:03:21
【问题描述】:

我是 Rails 新手,请多多包涵。我的问题很具体。我正在创建一个用户博客,他们可以在其中放置任何帖子。所以用户有博客,博客有帖子。因此,当用户创建博客时,他博客中的所有帖子都应该由他撰写。其他用户不能在他们的博客上写。

post_controller.rb

class PostsController < ApplicationController
  before_action :authenticate_user!
  before_action :authorize_user!, only: [:edit, :update, :destroy]

  expose :blog
  expose :post

  def show
  end

  def new
  end

  def edit
  end

  def create
    post.user = current_user
    post.save
    respond_with post, location: user_blog_path(post.blog.user, post.blog)
  end

  def update
    post.update(post_params)
    respond_with post, location: user_blog_path(post.blog.user, post.blog)
  end

  def destroy
    post.destroy
    respond_with post, location: user_blog_path(post.blog.user, post.blog)
  end

  private

  def authorize_user!
    authorize(post, :authorized?)
  end

  def post_params
    params.require(:post).permit(:title, :content, :user_id, :blog_id)
  end
end

我在这里使用权威人士来授权用户,当他们更新或销毁帖子时(用户只能更新或销毁他们自己的帖子)并且它完美地工作。

查看/帖子/新

.row
  .columns
    h2 = title("New post")

.row
  .medium-5.columns
    = simple_form_for post do |f|
      = f.error_notification

      .form-inputs
        = f.input :title
        = f.input :content
        = f.hidden_field :blog_id, value: blog.id
      .form-actions
        = f.button :submit

这里我使用隐藏表单来设置我从参数中获取的 blog_id。 Http 链接看起来像 http://localhost:3000/posts/new?blog_id=6。问题是每个用户都可以复制此链接来创建帖子(他们不是博客所有者)。

post_policy.rb

class PostPolicy < ApplicationPolicy
  def authorized?
    record.user == user
  end
end

在创建帖子之前我应该​​如何检查博客的所有者?也许我有错误的方式来创建这样的帖子(使用隐藏表单)。

创建新帖子的链接

= link_to 'New Post', new_post_path(blog_id: blog.id)

【问题讨论】:

  • 您的before_action 仅在编辑、更新和销毁时运行。不确定它是否能解决问题,但我认为您需要先将:create 添加到列表中。
  • @moveson 如果我添加 :create,没有人可以创建帖子。我想是因为在授权?方法我检查 post.user = 当前用户?但是我在创建后设置了post.user,所以在授权? post.user 总是为零
  • 在create 操作中设置post.user = current_user 后,尝试将authorize_user! 放在下一行。
  • @moveson 无论如何都不起作用

标签: ruby-on-rails ruby ruby-on-rails-4 pundit


【解决方案1】:

希望对你有用

application_controller.rb

  class ApplicationController

      include Pundit

      after_action :verify_authorized, except: :index
      after_action :verify_policy_scoped, only: :index

      before_action :authenticate_admin_user!

      helper_method :current_user

      def pundit_user
        current_admin_user
      end

      def current_user
        @current_user ||= User.find(current_admin_user.id)
      end

    end

posts_controller.rb

class PostsController < ApplicationController

  before_action :set_blog

  def new
    authorize(Post)
  end

  def edit
    @post = @blog.posts.find(params[:id])
    authorize(@post)
  end

  def index
    @posts = policy_scope(@blog.posts)
  end

  private

  def set_blog
    @blog = current_user.blogs.find(params[:blog_id])
  end

end

post_policy.rb

class PostPolicy < ApplicationPolicy

  def show?
    true
  end

  def index?
    true
  end

  def new?
    create?
  end

  def create?
    true
  end

  def edit?
    update?
  end

  def update?
    scope_include_object?
  end

  def destroy?
    scope_include_object?
  end

  class Scope < Scope

    def resolve
      scope.joins(:blog).where(blogs: { admin_user_id: user.id })
    end

  end

  def scope_include_object?
    scope.where(id: record.id).exists?
  end

end

routes.rb

Rails.application.routes.draw do
  devise_for :admin_users

  resources :blogs do
    resources :posts
  end
end

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多