Http 示例

最后更新于:2022-04-02 03:07:24

[TOC] ## 示例
auth_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/*, * ```

main.go ``` package main import ( "errors" "fmt" "github.com/casbin/casbin" "log" "net/http" "time" ) type User struct { ID int Name string Role string } type Users []User func (u Users) Exists(id int) bool { } func (u Users) FindByName(name string) (User, error) { for _, v := range u { if v.Name==name { return v,nil } } return User{},errors.New("not found") } func createUsers()Users { users :=Users{} users = append(users,User{ID: 1, Name: "Admin", Role: "admin"}) users = append(users,User{ID: 2, Name: "Sabine", Role: "member"}) users = append(users,User{ID: 3, Name: "Sepp", Role: "member"}) return users } func main() { // setup casbin auth rules authEnforcer, err := casbin.NewEnforcerSafe("./auth_conf", "./policy.csv") if err != nil { log.Fatal(err) } // setup session store engine := memstore.New(30 * time.Minute) sessionManager := session.Manage(engine, session.IdleTimeout(30*time.Minute), session.Persist(true), session.Secure(true)) // setup users users := createUsers() // setup routes mux := http.NewServeMux() mux.HandleFunc("/login", loginHandler(users)) mux.HandleFunc("/logout", logoutHandler()) mux.HandleFunc("/member/current", currentMemberHandler()) mux.HandleFunc("/member/role", memberRoleHandler()) mux.HandleFunc("/admin/stuff", adminHandler()) log.Print("Server started on localhost:8080") log.Fatal(http.ListenAndServe(":8080", sessionManager(Authorizer(authEnforcer, users)(mux)))) } func loginHandler(users Users) http.HandlerFunc { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { name := r.PostFormValue("name") user, err := users.FindByName(name) if err != nil { writeError(http.StatusBadRequest, "WRONG_CREDENTIALS", w, err) return } // setup session if err := session.RegenerateToken(r); err != nil { writeError(http.StatusInternalServerError, "ERROR", w, err) return } session.PutInt(r, "userID", user.ID) session.PutString(r, "role", user.Role) writeSuccess("SUCCESS", w) }) } func logoutHandler() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if err := session.Renew(r); err != nil { writeError(http.StatusInternalServerError, "ERROR", w, err) return } writeSuccess("SUCCESS", w) } } func currentMemberHandler() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { uid, err := session.GetInt(r, "userID") if err != nil { writeError(http.StatusInternalServerError, "ERROR", w, err) return } writeSuccess(fmt.Sprintf("User with ID: %d", uid), w) } } func memberRoleHandler() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { role, err := session.GetString(r, "role") if err != nil { writeError(http.StatusInternalServerError, "ERROR", w, err) return } writeSuccess(fmt.Sprintf("User with Role: %s", role), w) } } func adminHandler() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { writeSuccess("I'm an Admin!", w) } } func Authorizer(e *casbin.Enforcer, users Users) func(next http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // 从session 中获取 role role, err := session.GetString(r, "role") if err != nil { writeError(http.StatusInternalServerError, "ERROR", w, err) return } //如果用户没有用户角色,我们将其设置为anonymous if role == "" { role = "anonymous" } // if it's a member, check if the user still exists if role == "member" { uid, err := session.GetInt(r, "userID") if err != nil { writeError(http.StatusInternalServerError, "ERROR", w, err) return } exists := users.Exists(uid) if !exists { writeError(http.StatusForbidden, "FORBIDDEN", w, errors.New("user does not exist")) return } } // 在此处进行 权限判断 res, err := e.EnforceSafe(role, r.URL.Path, r.Method) if err != nil { writeError(http.StatusInternalServerError, "ERROR", w, err) return } if res { next.ServeHTTP(w, r) } else { writeError(http.StatusForbidden, "FORBIDDEN", w, errors.New("unauthorized")) return } }) } } ```

';