Go语言中文网,致力于每日分享编码、开源等知识,欢迎关注我,会有意想不到的收获!
![63e6331634e61083c7c30130cdc9bb38.png](https://i-blog.csdnimg.cn/blog_migrate/103d8d56f3e3acec55cdc66f26848e41.jpeg)
身份认证和授权对 web 应用的安全至关重要。最近,我用 Go 完成了我的第一个正式的 web 应用,这篇文章是在这个过程中我所学到的部分内容。
本文中,我们的关注点在于如何在 web 应用中使用开源的 casbin 库进行 HTTP 权限控制。同时,在示例代码中我们使用了 scs 库进行 session 管理。
下面的例子十分基础,希望它尽可能的展示了如何在 Go web 应用中实现权限控制。为了更侧重于展示 casbin 的使用,我们尽量简化业务逻辑(例如:不需密码的登陆操作)。我们一起来看一下!
注意:请不要在生产环境中使用所示的用例代码,该例子侧重于描述清晰,而不是安全性。
建立
首先,我们创建一个 User 模型,并实现了相应方法:
type User struct { ID int Name string Role string}type Users []Userfunc (u Users) Exists(id int) bool { ...}func (u Users) FindByName(name string) (User, error) { ...}
接着配置 casbin 所需文件。这里我们需要一个配置文件和一个策略文件。配置文件使用 PERM 元模型。PERM 表示策略(Policy)、效果(Effect)、请求(Request)和匹配器(Matchers)。
在 auth_model.conf 配置文件中有如下内容:
[request_definition]r = sub, obj, act[policy_definition]p = sub, obj, act[policy_effect]e = some(where (p.eft == allow))[matchers]m = r.sub == p.sub && keyMatch(r.obj, p.obj) && (r.act == p.act || p.act == "*")
其中定义了请求和策略来表示主体,客体和动作。在本例中,主体表示用户角色,客体表示访问路径,action 表示请求方法(例:GET, POST 等)。
匹配器定义了策略是如何匹配的,可以通过直接定义主体,或者使用像 keyMatch 这样的帮助方法,它也可以匹配通配符。casbin 实际比这个简单的例子要强大得多,你可以用声明的方式定义各种自定义功能来达到轻松切换和维护鉴权配置的效果。
在安全性方面,我通常会选择最简单的解决方案,因为当系统开始变复杂和难以维护时,错误就开始发生。
在这个例子中,策略文件就是一个简单的 csv 文件,描述了哪些角色可以访问哪些路径等。
policy.csv 文件格式如下:
p, admin, /*, *p, anonymous, /login, *p, member, /logout, *p, member, /member/*, *
这个配置文件十分简单。在这个例子中,我们简单的定义了 admin 角色可以访问所有内容,member 角色可以访问以 /member/ 开头的路径和 logout 路径,未认证用户可以登陆。
这种形式的好处在于即使应用具有许多规则和用户角色,它仍然是可维护的。
执行
让我们从 main 函数开始,将所有的东西都配置好,并启动 http 服务器:
func main() { // setup casbin auth rules authEnforcer, err := casbin.NewEnforcerSafe("./auth_model.conf