注意,本例是簡單講解casbin的作用,並非詳細文檔,詳細文檔可查看官方文章。

首先創建2個文件:auth_model.conf和policy.csv
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 == "*")
policy.csv
p, admin, /*, * p, anonymous, /login, * p, member, /logout, * p, member, /member/*, *
上述2個文件的內容是casbin的核心,說出了casbin的作用:即規定了某某角色,對某某資源,具有某某權限。
單獨拿HTTP場景來說:
sub代表 用戶角色;
obj代表 用戶想訪問的路徑;
act代表 請求方法(GET或POST等);
比如上面的第一行,admin對任意路徑(/*),具有所有權限(*)。
而匿名角色只能訪問登錄頁面(/login)。
會員角色對/member/下的任意路徑,既可以發送GET,也可以發送POST。

main.go
package main
import (
"fmt"
"github.com/casbin/casbin/v2"
"log"
"net/http"
)
func authorizer(e *casbin.Enforcer) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
url := r.URL.Path
queries := r.URL.Query()
username := queries.Get("user")
if username == "" {
username = "anonymous"
}
act := r.Method
// 驗證
ok, err := e.Enforce(username, url, act)
if err != nil {}
if ok == true {
next.ServeHTTP(w, r)
} else {
w.WriteHeader(http.StatusForbidden)
fmt.Fprint(w, "你沒有權限訪問這個地方")
}
}
return http.HandlerFunc(fn)
}
}
func indexHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "這是首頁")
}
func memberHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "這是會員頁")
}
func main() {
authEnforcer, err := casbin.NewEnforcer("./auth_model.conf", "./policy.csv")
if err != nil {
log.Fatal(err)
}
router := http.NewServeMux()
router.HandleFunc("/", indexHandler)
router.HandleFunc("/member/", memberHandler)
log.Fatal(http.ListenAndServe(":8080", authorizer(authEnforcer)(router)))
}
最后進行測試
由於只是簡化測試,因此用url參數來模擬用戶


因為我們在policy.csv中,沒有定義member與/的關系,因此在驗證的使用,沒有通過。


