| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- package main
- import (
- "context"
- "encoding/json"
- "io"
- "log"
- "net/http"
- "code.clickto.dev/weiym/permlib"
- )
- type CreateUserReq struct {
- Username string `json:"username"`
- Email string `json:"email" perm:"data:user:email:write"`
- Phone string `json:"phone" perm:"data:user:phone:write"`
- }
- type UserListResp struct {
- ID int64 `json:"id"`
- Username string `json:"username"`
- Email string `json:"email" perm:"data:user:email:read"`
- Phone string `json:"phone" perm:"data:user:phone:read"`
- }
- func writeJSON(w http.ResponseWriter, status int, body interface{}) {
- w.Header().Set("Content-Type", "application/json; charset=utf-8")
- w.WriteHeader(status)
- json.NewEncoder(w).Encode(body)
- }
- func main() {
- engine, err := permlib.New(permlib.Config{
- ProductCode: "crm",
- AppKey: "ak_crm",
- AppSecret: "sk_crm",
- PermServerAddr: "localhost:10002",
- FieldWriteMode: permlib.FieldWriteSilent,
- Callbacks: permlib.AuthCallbacks{
- OnError: func(w http.ResponseWriter, r *http.Request, httpStatus int, code int, msg string) {
- writeJSON(w, httpStatus, map[string]interface{}{
- "success": false,
- "errorCode": code,
- "errorMessage": msg,
- })
- },
- OnSuccess: func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc, user *permlib.UserInfo, hasDataPerm bool) {
- if !hasDataPerm {
- writeJSON(w, http.StatusOK, map[string]interface{}{
- "success": true,
- "data": map[string]interface{}{},
- })
- return
- }
- next(w, r)
- },
- },
- })
- if err != nil {
- log.Fatal(err)
- }
- if err := engine.Start(context.Background()); err != nil {
- log.Fatal(err)
- }
- mux := http.NewServeMux()
- // 公开接口:产品端自己实现 handler,完全控制响应格式
- mux.HandleFunc("POST /api/auth/login", makeLoginHandler(engine))
- mux.HandleFunc("POST /api/auth/refreshToken", makeRefreshTokenHandler(engine))
- // 鉴权接口:通过 AuthMiddlewareWithOpts 套上鉴权 + 字段过滤
- mux.HandleFunc("POST /api/user/create", engine.AuthMiddleware(createUser))
- mux.HandleFunc("POST /api/user/list", engine.AuthMiddleware(listUsers))
- log.Println("server listening on :8080")
- log.Fatal(http.ListenAndServe(":8080", mux))
- }
- func makeLoginHandler(engine *permlib.Engine) http.HandlerFunc {
- return func(w http.ResponseWriter, r *http.Request) {
- body, err := io.ReadAll(r.Body)
- r.Body.Close()
- if err != nil {
- writeJSON(w, http.StatusBadRequest, map[string]interface{}{"success": false, "errorMessage": "请求体读取失败"})
- return
- }
- var req struct {
- Username string `json:"username"`
- Password string `json:"password"`
- }
- if err := json.Unmarshal(body, &req); err != nil || req.Username == "" || req.Password == "" {
- writeJSON(w, http.StatusBadRequest, map[string]interface{}{"success": false, "errorMessage": "用户名和密码不能为空"})
- return
- }
- result, err := engine.Login(r.Context(), req.Username, req.Password)
- if err != nil {
- writeJSON(w, http.StatusUnauthorized, map[string]interface{}{"success": false, "errorMessage": err.Error()})
- return
- }
- writeJSON(w, http.StatusOK, map[string]interface{}{
- "success": true,
- "data": map[string]interface{}{
- "accessToken": result.AccessToken,
- "refreshToken": result.RefreshToken,
- "expires": result.Expires,
- "userId": result.UserId,
- "username": result.Username,
- "nickname": result.Nickname,
- "memberType": result.MemberType,
- "perms": result.Perms,
- },
- })
- }
- }
- func makeRefreshTokenHandler(engine *permlib.Engine) http.HandlerFunc {
- return func(w http.ResponseWriter, r *http.Request) {
- body, err := io.ReadAll(r.Body)
- r.Body.Close()
- if err != nil {
- writeJSON(w, http.StatusBadRequest, map[string]interface{}{"success": false, "errorMessage": "请求体读取失败"})
- return
- }
- var req struct {
- RefreshToken string `json:"refreshToken"`
- }
- if err := json.Unmarshal(body, &req); err != nil || req.RefreshToken == "" {
- writeJSON(w, http.StatusBadRequest, map[string]interface{}{"success": false, "errorMessage": "refreshToken不能为空"})
- return
- }
- result, err := engine.RefreshToken(r.Context(), req.RefreshToken)
- if err != nil {
- writeJSON(w, http.StatusUnauthorized, map[string]interface{}{"success": false, "errorMessage": err.Error()})
- return
- }
- writeJSON(w, http.StatusOK, map[string]interface{}{
- "success": true,
- "data": map[string]interface{}{
- "accessToken": result.AccessToken,
- "refreshToken": result.RefreshToken,
- "expires": result.Expires,
- "perms": result.Perms,
- },
- })
- }
- }
- func createUser(w http.ResponseWriter, r *http.Request) {
- user := permlib.GetUser(r.Context())
- writeJSON(w, http.StatusOK, map[string]interface{}{
- "success": true,
- "data": map[string]interface{}{"createdBy": user.Username},
- })
- }
- func listUsers(w http.ResponseWriter, r *http.Request) {
- users := []UserListResp{
- {ID: 1, Username: "alice", Email: "alice@example.com", Phone: "13800001111"},
- {ID: 2, Username: "bob", Email: "bob@example.com", Phone: "13800002222"},
- }
- writeJSON(w, http.StatusOK, map[string]interface{}{
- "success": true,
- "data": users,
- })
- }
|