在人们开始使用Rails 4之后, cancan的复杂以及兼容性修复不及时而遭人诟病,大家将目光投向了新的工具 Pundit。

Pundit是一个纯ruby的gem,用于权限验证。

基本思路

Pundit针对当前模型对象,以及操作,会去相应的模型的policy中寻找操作验证的方法,继而实现验证。

也就是说,只要是任何一个class,需要对他的实例进行验证,只要将验证规则写在对应的policy中即可。

安装及初始化

# Gemfile
gem `pundit`

$ bundle install

$ rails g pundit:install 生成默认的policy文件,路径为app/policies/application_policy.rb

在ApplicationController里添加:

class ApplicationController < ActionController::Base# ...include Pundit# ...
end

添加验证

如果要针对Article模型的实例,进行权限验证,则继续执行:

$ rails generate pundit:policy article => 生成 app/policies/article_policy.rb

# app/policies/article_policy.rb
class ArticlePolicy < ApplicationPolicyclass Scope < Struct.new(:user, :scope)def resolvescopeendend
end

假设在articles_controller里有这么一段:

def update@article = Article.find(params[:id])# 我们要在这里验证 current_user对这个@atilce是否有权限@article.update_atttributes(article_arrtibutes)
end

我们在ArticlePolicy添加一个方法,来验证用户是否有这个权限。方法的命名习惯于以问好结尾。

# app/policies/article_policy.rb
class ArticlePolicy < ApplicationPolicyclass Scope < Struct.new(:user, :scope)def resolvescopeendenddef update?record.creator_id == user.idend
end

这其中 uesr和 record来自于ApplicationPolicy。

class ApplicationPolicyattr_reader :user, :recorddef initialize(user, record)@user = user@record = recordend
end

然后在ArticlesContoller里加入验证:

def update@article = Article.find(params[:id])authorize @article, :update?@article.update_atttributes(article_arrtibutes)
end

由于action_name和验证方法的名字相同,所以可以简单写成:

def update@article = Article.find(params[:id])authorize @article@article.update_atttributes(article_arrtibutes)
end

这时,我们已经有了权限验证,当用户不具备权限的时候rails会抛出错误;不过我们要做的还没有结束,我们需要捕获这个错误并进行相关处理。

我们的application_controller应该变成这样:

class ApplicationController < ActionController::Base# ...include Punditrescue_from Pundit::NotAuthorizedError, with: :user_not_authorizedprivatedef user_not_authorizedredirect_to root_url, :alert => "You don't have permission to those resources."endend

这样就可以在用户不具备权限时,跳转至root_url并给出相应提示了。

测试

参考这里: Testing Pundit Policies with RSpec

接下来我们对刚才的操作进行测试,以rspec为例:

首先,在spec_helper加入:

require 'pundit/rspec'

然后,生成测试文件,置于spec/policies/article_policy_spec.rb

require 'spec_helper'describe ArticlePolicy dosubject { ArticlePolicy.new(user, article) }let(:article) { create :article }context 'for a guest' dolet(:user) { nil }it { should_not allow(:update) }endcontext 'for the write ' dolet(:user) { article.creator }it { should     allow(:index) }endcontext 'for an other writer' dolet(:user) { create :user }it { should_not allow(:update) }end
end

注意:这里的allow方法并非Pundit提供,而是我们自定义的matcher:

# spec/support/pundit_matcher.rbRSpec::Matchers.define :allow do |action|match do |policy|policy.public_send("#{action}?")endfailure_message_for_should do |policy|"#{policy.class} does not permit #{action} on #{policy.record} for #{policy.user.inspect}."endfailure_message_for_should_not do |policy|"#{policy.class} does not forbid #{action} on #{policy.record} for #{policy.user.inspect}."end
end

Tags:

Posted on: 2014-07-16

Rails权限验证工具Pundit相关推荐

  1. shopnc 支持 支付宝快捷登陆 shopnc权限验证原理说明

    为目前使用的是shopnc商场二次开发,shopnc本身做了qq互联和微博快捷登陆的api,做成了集成通用的接口 首先说下基本的这种类型的api访问方式,首先,的有个配置文件,配置你申请的id和key ...

  2. [Abp 源码分析]权限验证

    点击上方蓝字关注我们 0.简介 Abp 本身集成了一套权限验证体系,通过 ASP.NET Core 的过滤器与 Castle 的拦截器进行拦截请求,并进行权限验证.在 Abp 框架内部,权限分为两块, ...

  3. 【 .NET Core 3.0 】框架之五 || JWT权限验证

    前言 关于JWT一共三篇 姊妹篇,内容分别从简单到复杂,一定要多看多想: 一.Swagger的使用 3.3 JWT权限验证[修改] 二.解决JWT权限验证过期问题 三.JWT完美实现权限与接口的动态分 ...

  4. C# 微信JS-SDK之config接口注入权限验证invalid signature签名错误

    文章目录 1.开发环境 2.我的代码 3.问题描述 4.问题分析 5.问题根源 6.解决办法 记一次使用微信JS-SDK分享接口,config接口注入权限验证失败, 提示invalid signatu ...

  5. springboot+shiro+jwt实现登录+权限验证

    目录 一.简介: JWT优点: JWT缺点: shiro: JWT: 1.JWT头 2.有效载荷 3.签名哈希 4.Base64URL算法 二.实现 1.引入maven依赖 2.编写shiro配置类 ...

  6. 权限管理工具的使用方法

    权限管理工具的使用 在当今商业软件的开发中有一项功能是必不可少的,这就是权限工具,想必大家对权限这个词不会太陌生,应为在我们身边的很多软件上都用到了权限,比如说最常见的Windows操作系统,就使用到 ...

  7. .NET MVC5简介(四)Filter和AuthorizeAttribute权限验证

    在webform中,验证的流程大致如下图: 在AOP中: 在Filter中: AuthorizeAttribute权限验证 登录后有权限控制,有的页面是需要用户登录才能访问的,需要在访问页面增加一个验 ...

  8. MySql 中的skip-grant-tables(跳过权限验证的问题)

    https://blog.csdn.net/qq_29971371/article/details/81219837 安装MySql 设置my.ini配置文件的时候,常常会添加 skip-grant- ...

  9. 【ASP.NET】ASP.NET中权限验证使用OnAuthorization实现

    在项目开发中,通常我们都会涉及到用户登录才能访问的网页,比如购物网站,我们浏览商品,添加购物车(以前开发的时候在这里就需要登录用户,但是现在有了缓存的实现,这里可以将商品加入缓存,等到结账的时候再登录 ...

最新文章

  1. 【MATLAB】二维绘图 ( 绘制二维图像 | 设置图像样式 )
  2. 联合国和平音乐会主题粮安天下 国际农民丰收节贸易会贺电
  3. 布局文件中出现的错误
  4. [Nescafé41]异化多肽(多项式求逆元)
  5. 转liunx 常用命令
  6. 常见服务器返回的错误代码(转)
  7. 二十三种设计模式[4] - 原型模式(Prototype Pattern)
  8. 第一个被赋予公明身份的机器人_机器人索菲亚扬言要消灭人类!曾经狂妄无比,现在过得如何...
  9. 记一次自动提醒钉钉机器人的诞生
  10. font-family字体-常用字体中英文对照表
  11. 我爱你——再高级一点
  12. archlinux安装QQ微信
  13. 后端线上服务监控与报警方案
  14. Android模拟器的下载与安装(Windows)
  15. 知识图谱入门学习笔记(二)-知识表示
  16. 函数平移口诀_二次函数平移规律口诀
  17. Win10+VS2019+OpenGL安装
  18. linux boot菜单列表,/boot/grub/menu.lst详解
  19. 安卓 php 环境,初尝PFA ----- PHP 在 Android 环境配置搭建
  20. c语言inv函数怎么用,1 怎样学习c语言

热门文章

  1. 触摸查询系统服务器注册码,多媒体触摸查询系统旗舰版-用户手册(20161215.pdf
  2. 河北省考计算机知识,河北省职称计算机考试基础知识试题及答案.pdf
  3. python使用opencv对图像添加(高斯/椒盐/泊松/斑点)噪声
  4. 在EasyUI项目中使用FileBox控件实现文件上传处理
  5. 2020年中国高温合金行业发展现状及竞争格局分析,20年高温合金供需缺口扩大,依赖进口「图」
  6. 在linux系统中通过fw_printenv查看和设置u-boot中的环境变量
  7. 才上架不久的超级玛丽3号max要停售保70岁版本?这对我们消费者有什么影响,一文解析
  8. 一次访问web服务器的详细通信过程
  9. bugku-writeup-MISC-赛博朋克
  10. 微信小程序-form表单保存提交与重置