权限控制 - Casbin

最近在研究 iam 相关的内容,iam 即身份访问管理(identify access management) 身份: 用户在整个系统体系中扮演什么样的角色 访问管理:对身份的权限控制。 那既然谈到权限控制,不得不谈谈 casbin, casbin 目前是 github 上在权限控制处理方面 star 数是最多的,虽然之前没接触过 casbin,但也调研了一段时间,从易用性,扩展性,实现上来谈谈 casbin。 核心概念 权限模型目前主流的主要包括acl, rbac, abac。 简单先从这几个模型说起。而了解这几个模型之前,我们先约定一下一些术语。 subject 主体,在一般的权限体系中,主体一般是指操作者,比如某个用户,某个角色(其实角色最下面也是个用户),当然更广义的讲,可能主体也可以代表其他需要约束的对象,比如在物联网中,他也可以代表一个iot设备。 resouce 资源,一切可操作的实体都可以当做是一种资源,比如aliyun上的我们购买的ecs实例,后台系统的一个user action 操作,主体对资源的操作,比如我们可以对ecs实例进行开机,关机,重启等操作,可以新增,删除,编辑一个user。 condition 操作的条件,一般基于主体与资源的约事条件,比如 user 的ip必须在172.168.0.1/24的段内 effect 影响效力,一般只有allow(允许)/deny(不允许) 有了这些术语,我们去解释对应的权限模型,可能更知道不同模型的区别 ACL acl(访问控制列表),他代表的是,哪些用户(subject)或系统进程可以访问(action)资源(resource) 如果某个文件 apple.jpg(resource) 的 ACL 包含(Alice(subject): read(action),write(action);Bob(subject): read(action)),这将赋予 Alice 读写文件的权限,而只赋予 Bob 读取文件的权限。 RBAC ABAC casbin 中的概念 理解casbin,最主要理解其核心思路,casbin中的核心思路是使用policy(策略)中的规则去应用到model(模型)中,model 是一个规则引擎,帮我们处理一个主体(subject)是否有操作(action)某个资源(subject)的权限。 policy策略:一组规则的集合, 规则 model模型:对每行规则进行解析 因此,对于我们使用者来说,大多时候仅仅只需要关注policy和model就行。 model 初览 在model层面,casbin又基于 PERM (Policy, Effect, Request, Matcher). 一个完整的model(perm)文件格式如下:...

九月 14, 2023 · nobject

swagger的使用

随着RESTful API的流行,Swagger已经成为了一种通用的API描述和文档格式。它可以帮助开发者描述、测试和文档化RESTful API。在本文中,我们将介绍在go中如何使用相应的库生成swagger文档。在golang中, 有两款可以生成swagger的库,一般我们选择https://github.com/swaggo/swag,还有另一款https://github.com/go-swagger/go-swagger,相对来说,使用起来swag更易用一点 安装 1 go install github.com/swaggo/swag/cmd/swag@latest 默认情况下,会安装在go path相关的目录下,该目录一般已经加入环境变量,若没有加入环境变量,我们可根据每种系统的不同,手动加入至环境变量中 检测是否安装成功: 1 swag -v 返回具体的版本号即成功: 1 swag.exe version v1.8.12 使用 路由绑定 我们使用的是gin框架,swag对gin也有集成封装, 我们可以在gin的路由绑定至对应的swagger文档 1 2 3 // swagger文档查看路径 url := ginSwagger.URL("/swagger/doc.json") // The url pointing to API definition r.GET("swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler, url)) 依赖库: 1 2 swaggerFiles "github.com/swaggo/files" "github.com/swaggo/gin-swagger" 路由注释 1 2 3 4 5 6 7 8 9 10 // ListUser // @Summary 查询用户信息 // @Tags 用户 // @Description 查询用户信息 // @Produce json // @Param UserId header string true "当前用户id" // @Param query query dto....

八月 27, 2023 · nobject

go分享

go的goroutine go中最重要的概念之一就是协程,协程的创建方式也很简单,go func()就简单的创建了一个协程,虽然go语言中并没有规定协程的 创建数据限制,每个协程相对于线程的成本也很低,协程最小占用只有2Kb, 1000个协程才2M,所以成本极低。 但创建容易的同时也应该注意以下几点: 对于panic捕获的安全性 我们一般使用go func()直接创建协程了,但一般在代码中,很少直接这么使用,一般会在外面再封装一层。具体的封装方式类似这样: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package thread import ( "fmt" "runtime/debug" ) func GoSafe(fn func()) { go RunSafe(fn) } func RunSafe(fn func()) { // 可以將panic上报给sentry等报警平台,或者钉钉,飞书机器人的钩子等 defer func() { if p := recover(); p != nil { fmt.Printf("RunSafe capture crash,msg: %s \n %s ", fmt.Sprint(p), string(debug.Stack())) } }() fn() } 原因很简单,go语言外层的defer是捕获不了内部goroutine的异常的,所以如果内部的goroutine发生panic,那会导致整个程序直接crash。 因此,使用goroutine的话最好再加一层安全封装,以防止潜在的panic导致的crash。...

五月 24, 2023 · nobject

Yaml 语法

yaml是工作中遇到比较多的标记语言,特别在k8s横行其道的年代, yaml简直就是标配, 到处都是yaml。yaml的语法还是简单的,在此只 是做点小记录 yaml的基本使用 简单的对象关系 1 name: "hua" ## 在同一行,:后一定要加空格 行内对象嵌套关系 1 info: {name: "hua", age: 32} 数组关系 1 2 3 - Bird - Cat - Dog 行内数组 1 animals: [Bird, Cat, Dog] 子数组 1 2 3 4 - - Bird - Cat - Dog

五月 18, 2023 · nobject

网关traefik入门级使用

基本概念 EntryPoints EntryPoints 是进入traefik的入口点,定义端口接收数据包,可以是tcp也可以udp的包。 Routers Middlewares 附加在路由之上,中间件可以在发送至后端服务器之前处理请求或响应。 Services 简单部署 可以写一个docker-compose.yaml文件编排traefik与后端服务whoami 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 version: '3' services: reverse-proxy: # The official v2 Traefik docker image image: traefik:v2.10 # Enables the web UI and tells Traefik to listen to docker command: --api.insecure=true --providers.docker --accesslog=true ports: # The HTTP port - "80:80" # The Web UI (enabled by --api....

五月 12, 2023 · nobject

网关traefik调研

五月 11, 2023 · nobject

网关gloo调研

五月 8, 2023 · nobject

golang 面试题集

Go 中的 rune 和 byte 有什么区别? Go 中的 string 和 []byte 有什么区别? 什么是深拷贝和浅拷贝? Go 中的 slice 和 array 有什么区别?slice的扩容机制与扩容时机,使用slice该注意什么 说说 Go 中闭包的底层原理? 说一下 GMP 模型的原理 Go 的默认栈大小是多少?最大值多少? Go 中的分段栈和连续栈的区别? 简述一下 Go 栈空间的扩容/缩容过程? GMP 为什么要有 P ? Go 中的 GC 演变是怎样的? 哪些情况会导致协程泄露? 内存分配原理 gin框架的路由实现原理 go中http库的实现原理 代码题:使用n个并发,输出[]string{“a”, “b”, “c”, “d”, “e”, “f”, “g”} 代码题:实现一个简单的协程池 代码题:使用并发编排,使abc三个各输出100次 map的底层实现原理,如果一个协程在delete, 一个协程在读,会出现什么问题,原因是什么 uinptr和unsafe.Pointer的区别 singleFlight存在的坑

二月 22, 2023 · nobject

算法笔记

滑动窗口 双指针 贪心 动态规划 排序 二叉树

二月 22, 2023 · nobject

算法笔记 - 二叉树

递归模板 1 2 3 4 5 6 7 8 9 10 func traverse(root *TreeNode) { if root == nil { return } // 前序位置 traverse(root.Left) // 中序位置 traverse(root.Right) // 后序位置 } 层序遍历 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 // 输入一棵二叉树的根节点,层序遍历这棵二叉树 func levelTraverse(root *TreeNode) { if root == nil { return } q := make([]*TreeNode, 0) q = append(q, root) // 从上到下遍历二叉树的每一层 for len(q) > 0 { sz := len(q) // 从左到右遍历每一层的每个节点 for i := 0; i < sz; i++ { cur := q[0] q = q[1:] // 将下一层节点放入队列 if cur....

二月 22, 2023 · nobject

[转]golang面试 - Rune与Byte的区别

以下文章转自 https://iswbm.com/517.html 一个字符串是由若干个字符组合而成的,比如 hello,就由 5 个字符组成。 在 Go 中字符类型有两种,分别是: byte 类型:字节,是 uint8 的别名类型 rune 类型:字符,是 int32 的别名类型 byte 和 rune ,虽然都能表示一个字符,但 byte 只能表示 ASCII 码表中的一个字符(ASCII 码表总共有 256 个字符),数量远远不如 rune 多。 rune 表示的是 Unicode字符中的任一字符,而我们都知道,Unicode 是一个可以表示世界范围内的绝大部分字符的编码, 这张表里几乎包含了全世界的所有的字符,当然中文也不在话下。 能表示的字符更多,意味着它占用的空间,也要更大,所占空间是 4个 byte 的大小。 下面以一段代码来验证一下他们的占用空间的差异 1 2 3 4 5 6 7 8 var a byte = 'A' var b rune = 'B' fmt.Printf("a 占用 %d 个字节数\n", unsafe.Sizeof(a)) fmt.Printf("b 占用 %d 个字节数\n",unsafe.Sizeof(b)) // output a 占用 1 个字节数 b 占用 4 个字节数 参考文档: https://iswbm....

十一月 4, 2022 · nobject

golang面试 - channel全解析

channel 什么情况下会出现panic 1 2 3 1. 试图往已close的channel继续发送 2. 试图关闭已关闭的channel 3. 试图关闭一个nil的channel 向为nil的channel发送数据会怎样 1 2 3 给定一个 nil channel c: <-c 从 c 接收将永远阻塞 c <- v 发送值到 c 会永远阻塞 channel close后读的问题 1 2 3 4 5 6 7 8 9 10 11 12 13 14 关闭后继续读数据,已在缓冲区内的可以读取到数据,而后得到的是零值(对于int,就是0)。 z 我们可以通过for循环遍历channel,来获取到已经写入的值 for _, v := range channel{ } 对于可能获取到零值,我们可以使用断言判断,ok为false代表channel已关闭后读取的 value, ok := <- channel 也可以在close channel之后有意将channel 置为 nil, 如此再使用,并不会读取到零值 对于不带缓冲的ch,和带缓冲的一样,channel close掉之后并不影响读,只影响写入 channel的底层结构 底层结构体 1 2 3 4 5 6 7 8 9 10 11 12 13 14 type hchan struct { qcount uint // total data in the queue 代表 chan 中已经接收但还没被取走的元素的个数。内建函数 len 可以返回这个字段的值。 dataqsiz uint // size of the circular queue 循环队列的大小 buf unsafe....

十一月 4, 2022 · nobject