美文网首页Ruby & RailsRubyRuby on Rails
ruby on rails中如何使用Pundit进行权限管理

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

作者: 程序员小哥哥 | 来源:发表于2017-09-01 20:38 被阅读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在实例化的时候,会初始化这个属性

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

    相关文章

      网友评论

        本文标题:ruby on rails中如何使用Pundit进行权限管理

        本文链接:https://www.haomeiwen.com/subject/cbmkjxtx.html