go gin+casbin RBAC 简单例子

go gin+casbin RBAC 简单例子

说明


利用的库:
github.com/casbin/casbin
github.com/gin-gonic/gin
github.com/facebookgo/inject
本文为 参考此项目: https://github.com/LyricTian/gin-admin ,强烈推荐!!!

casbin文档: https://casbin.org/zh-CN/

下面例子 未利用 casbin 的 adapter, 而是启动的时候 先初始化,
然后通过数据库里面的 对应关系 ,动态加载所有的 权限条目

然后通过中间件去判断,如果有更新,可以动态修改更新 权限条目.

例子

目录

代码


rbac_model.conf

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[role_definition]
g = _, _

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = g(r.sub, p.sub) == true     && keyMatch2(r.obj, p.obj) == true     && regexMatch(r.act, p.act) == true 

b_auth.go 

package bll

//gin-allin/models  为自己的项目  请忽略
import (
   "gin-allin/models"
   "github.com/casbin/casbin"
)

//models.Auth  为 User表     实际可以写成自己的USER 表
type Role struct {
   Role      *models.Auth     `inject:""`
   Enforcer  *casbin.Enforcer `inject:""`
}

// LoadPolicy 加载角色权限策略,
func (a *Role) LoadPolicy(roleID string) error {
   a.Enforcer.AddPolicy(roleID, "/api/v1/auth_info","GET")
   return nil
}

b_common.go

package bll

//把 权限表  注入到 Common
type Common struct {
   Role   *Role    `inject:""`
}

inject.go
package inject

import (
   "gin-allin/bll"
   "github.com/casbin/casbin"
   "github.com/facebookgo/inject"
   "os"
)

// Object 注入对象
type Object struct {
   Common     *bll.Common
   Enforcer   *casbin.Enforcer
}

// Init 初始化依赖注入
func Init() *Object {
   g := new(inject.Graph)

   // 注入casbin
   dir, _ := os.Getwd()
   path := dir + "\\src\\gin-allin\\conf\\rbac_model.conf"
   enforcer := casbin.NewEnforcer(path, false)
   _ = g.Provide(&inject.Object{Value: enforcer})

   //  注入Common  也就是 Role
   Common := new(bll.Common)
   _ = g.Provide(&inject.Object{Value: Common})

   if err := g.Populate(); err != nil {
      panic("初始化依赖注入发生错误:" + err.Error())
   }

   // 返回 注入完的对象
   return &Object{
      Enforcer:  enforcer,
      Common :Common,
   }
}

casb.go

package casb

import (
   "gin-allin/inject"
   "github.com/gin-gonic/gin"
   "net/http"
)

// 权限判断
func CasbinMiddleware(obj *inject.Object) gin.HandlerFunc {
   return func(c *gin.Context) {

      // 判断   权限 是否为 true
      if b, err := obj.Enforcer.EnforceSafe("hequan", c.Request.URL.Path, c.Request.Method); err != nil {
         c.JSON(http.StatusUnauthorized, gin.H{
            "code": "权限 判断错误",
            "msg":  "权限 判断错误",
            "data": "权限 判断错误",
         })
         c.Abort()
         return
      } else if !b {

         c.JSON(http.StatusUnauthorized, gin.H{
            "code": "没有权限",
            "msg":  "没有权限",
            "data": "没有权限",
         })
         c.Abort()
         return
      }
      c.Next()
   }
}

router.go

package routers

func InitRouter() *gin.Engine {
   // 生成对象
   obj := inject.Init()

   err := loadCasbinPolicyData(obj)

   if err != nil {
      panic("加载casbin策略数据发生错误:" + err.Error())
   }

   apiv1.Use(casb.CasbinMiddleware(obj))
}

// 加载casbin策略数据   加载 hequan  的一个权限
func loadCasbinPolicyData(obj *inject.Object) error {
   err := obj.Common.Role.LoadPolicy("hequan")
   if err != nil {
      fmt.Println(err)
      return err
   }
   return nil
}

结果

当 用户  hequan  去 访问   /api/v1/auth_info 时,会去判断是否有GET 权限,有就通过,没有就拒绝。

测试 可以把  用户名 写成其他的, 再重启启动,此时,中间件判断 不通过,就会返回 拒绝。

原文地址:http://blog.51cto.com/hequan/2341145

时间: 2024-10-03 12:50:05

go gin+casbin RBAC 简单例子的相关文章

go webssh 简单例子 (基于gin+ws+ssh)

项目地址 https://github.com/hequan2017/go-webssh go-webssh go版本 webssh 核心 本项目代码来自 https://github.com/dejavuzhou/felix ,只是把里面的webssh拿出来,修改了一下,做成webssh,特此说明.有需要可以查看此项目. 安装 修改 core/ssh.go 里面的账号密码地址等信息. 也可以自己修改成用密钥登录. func NewSshClient() (*ssh.Client, error)

从一个简单例子来理解js引用类型指针的工作方式

? 1 2 3 4 5 6 7 <script> var a = {n:1};  var b = a;   a.x = a = {n:2};  console.log(a.x);// --> undefined  console.log(b.x);// --> [object Object]  </script> 上面的例子看似简单,但结果并不好了解,很容易把人们给想绕了--"a.x不是指向对象a了么?为啥log(a.x)是undefined?".&

Hadoop RPC简单例子

jdk中已经提供了一个RPC框架-RMI,但是该PRC框架过于重量级并且可控之处比较少,所以Hadoop RPC实现了自定义的PRC框架. 同其他RPC框架一样,Hadoop RPC分为四个部分: (1)序列化层:Clent与Server端通信传递的信息采用了Hadoop里提供的序列化类或自定义的Writable类型: (2)函数调用层:Hadoop RPC通过动态代理以及java反射实现函数调用: (3)网络传输层:Hadoop RPC采用了基于TCP/IP的socket机制: (4)服务器端

extern外部方法使用C#简单例子

外部方法使用C#简单例子 1.增加引用using System.Runtime.InteropServices; 2.声明和实现的连接[DllImport("kernel32", SetLastError = true)] 3.声明外部方法public static extern int GetCurrentDirectory(int a, StringBuilder b); 4.对外部方法操作  GetCurrentDirectory(300, pathstring); using

事件简单例子

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Runtime.InteropServices; 6 7 namespace EventTest 8 { 9 /// <summary> 10 /// 事件订阅者类 11 /// </summary> 12 class Program 13 { 14 static v

spring mvc(注解)上传文件的简单例子

spring mvc(注解)上传文件的简单例子,这有几个需要注意的地方1.form的enctype=”multipart/form-data” 这个是上传文件必须的2.applicationContext.xml中 <bean id=”multipartResolver” class=”org.springframework.web.multipart.commons.CommonsMultipartResolver”/> 关于文件上传的配置不能少 大家可以看具体代码如下: web.xml &

自定义隐式转换和显式转换c#简单例子

自定义隐式转换和显式转换c#简单例子 (出自朱朱家园http://blog.csdn.net/zhgl7688) 例子:对用户user中,用户名first name和last name进行转换成合成一个限定长度为10个字符新name. 自定义隐式转换: namespace transduction { public partial class transductionForm : Form { public transductionForm() { InitializeComponent();

使用fastjson转换json的简单例子

pom添加依赖: <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.1.41</version> </dependency> 代码: package JsonTest.JsonTest; import java.util.ArrayList; import java.util.Hash

最简单例子图解JVM内存分配和回收

一.简介 JVM采用分代垃圾回收.在JVM的内存空间中把堆空间分为年老代和年轻代.将大量(据说是90%以上)创建了没多久就会消亡的对象存储在年轻代,而年老代中存放生命周期长久的实例对象.年轻代中又被分为Eden区(圣经中的伊甸园).和两个Survivor区.新的对象分配是首先放在Eden区,Survivor区作为Eden区和Old区的缓冲,在Survivor区的对象经历若干次收集仍然存活的,就会被转移到年老区. 简单讲,就是生命期短的对象放在一起,将少数生命期长的对象放在一起,分别采用不同的回收