Ruby & RailsRubyRuby on Rails

ruby on rails中如何使用Pundit进行权限管理

2017-09-01  本文已影响140人  程序员小哥哥

一:pundit介绍

有名的权限管理gem:
1.pundit:流行的权限管理(推荐,pundit更加适合大型项目,更加复杂的权限系统)
2.authority: 已经不维护了
3.cancancan: 比较老牌的权限管理的gem

作用:针对不同的用户执行不同的操作(不同的用户有不同的角色管理)
注意:用户级别的角色管理,pundit是不包含这个功能的,角色的管理需要我们自己来设计和实现
pundit这个gem是需要根据我们自己所需要的逻辑,比如哪样的用户能够干什么事情,说白了就是哪些用户
能够执行这个action,哪些用户可以执行特定的逻辑操作,总得来说,pundit主要是做后端的一个权限管理的一个gem.

二:Pundit安装和配置

1.在Gemfile中引入:

gem 'pundit'
bundle install

3.在app/controller/application_controller.rb中引入pundit这个模块

include Pundit

说明:引入pundit这个模块之后,我们就可以在controller和view中使用对应的方法来判断对应的权限了
4.运行pundit初始化命令

rails g pundit:install

说明:运行完这条命令之后会生成app/policies/application_policy.rb这个文件
5.在config/application.rb加入下面的语句,让其能自动加载

config.autoload_paths += %W[#{config.root}/app/policies]

三:Pundit的使用
这里首先要明确几点:
1.pundit策略的设置都是纯根据ruby的类来实现的
2.一个方法,比如index?是否返回true和false,是我们能够使用app/policies/application_policy.rb这个文件里user、record两个变量来判断当前的action是否返回true和false
3.policy设计的思路,每一个policy文件都是和模型对应的。比如传过来的是一个post这个record,pundit就会查找app/policies/下是否有PostPolicy这个类,然后调用这个类的同名的这个方法,进而判断权限,pundit和rails相似,有预先的约定和猜测。

举个例子:
只有这个用户发表的文章,他才有删改的权限
1.运行命令

rails g controller posts index show

在posts这个表创建个title这个列就行

app/model/user.rb

class User < ApplicationRecord
  has_many :user
end

app/model/post.rb

class Post < ApplicationRecord
  belongs_to :user
end

3.在rails c中创建下测试数据

user = User.first
user.posts.create title: "Post 1"
user.posts.create title: "Post 2"
user2 = User.last
user.posts.create title: "Post 3"
user.posts.create title: "Post 4"

4.在app/controllers/posts_controller.rb中增加简单的逻辑

class PostsController < ApplicationController
  
  def index
    @posts = Post.includes(:user)
  end

  def show
    @post = Post.find params[:id]
  end

  def edit
    @post = Post.find params[:id]
    authorize @post  #authorize是include Pundit提供的
  end

end

5.在config/routes.rb增加对应的路由

resources :posts

view层
app/views/posts/index.html.erb

<h1>Posts</h1>

<ul class="list-group">
  <% @posts.each do |post| %>
    <li class="list-group-item">
      <%= link_to post.title, post_path(post) %>,
      ID: <%= post.id %>,
      作者: <%= post.user.email %>
      <% if policy(post).edit? %>
        <%= link_to "编辑", edit_post_path(post), class: "btn btn-primary" %>
      <% end %>
    </li>
  <% end %>
</ul>

app/views/posts/show.html.erb

<h1>Posts</h1>

<h2><%= @post.title %></h2>
<p>作者: <%= @post.user.email %></p>

app/views/posts/edit.html.erb

<h1>Posts</h1>

<h2>编辑:<%= @post.title %></h2>

7.app/policies/policy.rb

class PostPolicy < ApplicationPolicy

  def edit?
    user.has_role?('admin') || user == record.user
  end

  def can_edit?
    true
  end

end

说明:会识别PostPolicy这个类,ApplicationPolicy有个user属性,指的是current_user,ApplicationPolicy在实例化的时候,会初始化这个属性

待续 写到一半想听会歌~~~

上一篇下一篇

猜你喜欢

热点阅读