使用 pundit gem rails 的授权设置
Authorization settings using pundit gem rails
我是 rails 的新人,请多多包涵。我的问题非常具体。我正在创建一个用户博客,他们可以在其中放置任何 post。所以 Users 有一个 blogs,而 blogs 有 posts。所以当用户创建博客时,他博客中的所有post都应该是他写的。其他用户不能在他们的博客上写。
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
这里我使用专家来授权用户,当他们更新或销毁 posts(用户只能更新或销毁他们自己的 posts)并且它完美地工作。
views/posts/new
.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 link 看起来像 http://localhost:3000/posts/new?blog_id=6。问题是每个用户都可以复制此 link 来创建 post(他们不是博客所有者)。
post_policy.rb
class PostPolicy < ApplicationPolicy
def authorized?
record.user == user
end
end
创建博客前post如何检查博客的所有者?也许我创建这样的 post 的方法不对(使用隐藏形式)。
Link 创建新的 post
= link_to 'New Post', new_post_path(blog_id: blog.id)
希望对你有用
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
我是 rails 的新人,请多多包涵。我的问题非常具体。我正在创建一个用户博客,他们可以在其中放置任何 post。所以 Users 有一个 blogs,而 blogs 有 posts。所以当用户创建博客时,他博客中的所有post都应该是他写的。其他用户不能在他们的博客上写。
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
这里我使用专家来授权用户,当他们更新或销毁 posts(用户只能更新或销毁他们自己的 posts)并且它完美地工作。
views/posts/new
.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 link 看起来像 http://localhost:3000/posts/new?blog_id=6。问题是每个用户都可以复制此 link 来创建 post(他们不是博客所有者)。
post_policy.rb
class PostPolicy < ApplicationPolicy
def authorized?
record.user == user
end
end
创建博客前post如何检查博客的所有者?也许我创建这样的 post 的方法不对(使用隐藏形式)。
Link 创建新的 post
= link_to 'New Post', new_post_path(blog_id: blog.id)
希望对你有用
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