ruby on rails中如何使用Pundit进行权限管理
一: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在实例化的时候,会初始化这个属性
待续 写到一半想听会歌~~~