Casbin的Model详解与使用

简介 文档:https://casbin.org/docs/zh-CN/overview Casbin 是干什么的文档说的很详细,就不在重复说了。相信很多人在看完文档之后,仍然是不知道 model.conf 和 policy.csv 是什么,看不懂里面的内容,有一种无从下手的感觉。 知识是有一个知识壁垒的,在你打破这个壁垒之前,你觉得很难,查资料看文章也是云里雾里的。但是在打破壁垒之后,掌握了这个知识在回头看,感觉真的好简单。 我查看了好几篇讲 Casbin 的文章,讲的都不是很通俗易懂,对于掌握了 Casbin 的人来看没什么,但是对于还不会的人看了还是有些云里雾里。所以我放弃了去搜索查看别人的经验,转而去读官方文档,在反反复复读了几遍文档之后终于掌握了 Casbin。不得不说在去学习一个新东西的时候,最好的办法就是去查看官方文档。接下来我会以不会 Casbin 的人的角度来尽可能通俗易懂的讲一讲 Casbin。 Model 与 Policy 接下来我们以 Linux 的文件系统权限为例来讲解 model.conf 和 policy.csv 。 语法 文档:https://casbin.org/docs/zh-CN/syntax-for-models Request 定义 不管哪个语言的 Casbin 都会提供一个 enforce 函数方法来校验是否有权限,[request_definition] 部分就定义了 enforce 函数的参数。 [request_definition] r = sub, obj, act sub, obj, act 经典三元组: 访问实体 (Subject),访问资源 (Object) 和访问方法 (Action),是可以自定义的。表示 enforce 函数需要按此顺序传入三个参数。 在 Linux 文件系统中: sub:代表用户 obj:代表访问的文件或文件夹 act:代表读、写或执行权限 在 RESTful 风格的 API 中:...

2022-10-25 · 3 分钟

Go标准库time.Parse方法的时区问题

time.Parse方法解析时间字符串得到的 time 的时区为UTC,并不会自动使用系统的默认时区。 parse, _ := time.Parse("2006-01-02 15:04:05", "2022-03-30 13:37:03") //UTC 0 fmt.Println(parse.Zone()) //CST 28800 fmt.Println(time.Now().Zone()) 如果我们不想要UTC时区,需要别的时区。可以使用time.ParseInLocation方法自行设置时区。 loc, _ := time.LoadLocation("Asia/Shanghai") parse, _ := time.ParseInLocation("2006-01-02 15:04:05", "2022-03-30 13:37:03", loc) //CST 28800 fmt.Println(parse.Zone()) //CST 28800 fmt.Println(time.Now().Zone())

2022-03-30 · 1 分钟

构建自己的go-gin-api脚手架(三)

Viper 地址:https://github.com/spf13/viper Viper 是适用于 Go 应用程序的完整配置解决方案。它被设计用于在应用程序中工作,并且可以处理所有类型的配置需求和格式。 文档 英文:可查看 Github 仓库的 README 文件 中文:可查看这篇文章的翻译 安装 go get github.com/spf13/viper 使用 新建配置文件/config/config.toml aaa = "111" bbb = "222" Viper 只需简单设置就可以读取到配置信息。 //设置文件路径 viper.AddConfigPath("/config") //设置文件名 viper.SetConfigName("config") //设置文件类型 viper.SetConfigType("toml") //读取配置文件 _ = viper.ReadInConfig() //监控配置文件变动 viper.WatchConfig() for { //输出所有配置 fmt.Println(viper.AllSettings()) time.Sleep(time.Second) } 多配置文件 随着项目开发,配置文件中的信息可能会越来越多,全部集中到一个文件中会变的难以管理。按功能分为不同的配置文件更易于管理,我们来自己实现一个多配置文件的方法。 方法一 使用MergeInConfig()方法将多个配置文件内容合并到一起。 在新建一个/config/router.toml配置文件 port = 8000 //设置文件路径 viper.AddConfigPath("/config") //设置文件名 viper.SetConfigName("config") //设置文件类型 viper.SetConfigType("toml") //读取配置文件 _ = viper.ReadInConfig() //设置第二个配置文件名称 viper.SetConfigName("router") //读取并合并已有配置 _ = viper....

2022-02-27 · 2 分钟

构建自己的go-gin-api脚手架(二)

在前文中我们已经成功的使用 Gin 框架搭建了一个简易的 API 服务,但是在一个项目中,所有的业务逻辑都写在 main.go 一个文件中显然是不合理的。所以接下来我们会对其进行重构,在整个搭建 go-gin-api 脚手架的过程中,会经常对其重构。 每当我要进行重构的时候,第一个步骤永远相同:我得确保即将修改的代码拥有一组可靠的测试。这些测试必不可少,因为尽管遵循重构手法可以使我避免绝大多数引入 bug 的情形,但我毕竟是人,毕竟有可能犯错。程序越大,我的修改不小心破坏其他代码的可能性就越大——在数字时代,软件的名字就是脆弱。 —— 《重构:改善既有代码的设计》 所以在此之前我们需要编写一套可靠的单元测试,来确保代码重构之后还能良好的运行。 Go 单元测试框架 testing testing 是 Go 标准库中提供的自动化测试支持,通过 go test 命令,能够自动执行如下形式的任何函数: func TestXxx(*testing.T) 注意:Xxx 可以是任何字母数字字符串,但是第一个字母不能是小写字母。 在这些函数中,使用 Error、Fail 或相关方法来发出失败信号。 要编写一个新的测试套件,需要创建一个名称以 _test.go 结尾的文件,该文件包含 TestXxx 函数,如上所述。 将该文件放在与被测试文件相同的包中。该文件将被排除在正常的程序包之外,但在运行 go test 命令时将被包含。 有关详细信息,请运行 go help test 和 go help testflag 了解。 标准库的 testing 实现比较简单,并不支持断言,需要写 if 判断。所以不考虑使用。 Testify 地址:https://github.com/stretchr/testify Testify 是基于 testing 编写的,所以测试文件与执行方式与其完全相同,并且支持断言方法。 编写测试 首先创建一个 main_test.go 的文件,写入以下代码并执行 go mod tidy更新依赖。...

2022-01-11 · 3 分钟

构建自己的go-gin-api脚手架(一)

目标 学习并掌握 Go 语言 学习并熟练使用 Gin 框架 学习并熟练使用 Go 热门常用的组件 搭建一个自己开箱即用的 api 框架 锻炼自己的封装抽象能力 初始化 使用 Goland 创建一个新项目go-gin-api。 可以看到项目中有一个 go.mod 的文件。 module go-gin-api go 1.17 Gin 安装 下载并安装 Gin : $ go get -u github.com/gin-gonic/gin go get: added github.com/gin-contrib/sse v0.1.0 go get: added github.com/gin-gonic/gin v1.7.7 go get: added github.com/go-playground/locales v0.13.0 ... 可以看到项目中又多了一个 go.sum 的文件,go.sum 文件详细罗列了当前项目直接或间接依赖的所有模块版本,并写明了那些模块版本的 SHA-256 哈希值以备 Go 在今后的操作中保证项目所依赖的那些模块版本不会被篡改。 go.mod 文件也发生了改变: module go-gin-api go 1.17 require ( github.com/gin-contrib/sse v0....

2022-01-10 · 1 分钟