package user import ( "fmt" "net/http" . "prime/basic" "strings" "github.com/gin-gonic/gin" "github.com/google/uuid" ) type UserForm struct { Username string `json:"username" binding:"required"` Password string `json:"password" binding:"required"` } var Authorized *gin.RouterGroup func init() { r := R() r.POST("/token", func(c *gin.Context) { // Parse JSON var json UserForm if c.Bind(&json) == nil { fmt.Printf("%+v\n", json) token, err := GenToken(json.Username, json.Password) if err == nil { fmt.Println(token) c.JSON(http.StatusOK, gin.H{"token": token}) } else { c.JSON(http.StatusUnauthorized, gin.H{"error": err.Error()}) } } }) r.POST("/user", func(c *gin.Context) { var json UserForm if c.Bind(&json) == nil { user, err := Register(json.Username, json.Password) if err == nil { c.JSON(http.StatusOK, gin.H{"uid": user.ID}) } else { c.JSON(http.StatusForbidden, gin.H{"error": err.Error()}) } } }) Authorized = r.Group("/", JWTAuthMiddleware()) Authorized.GET("home", homeHandler) Authorized.POST("message", func(c *gin.Context) { user := c.MustGet("username").(string) fmt.Printf("username=%s\n", user) // Parse JSON var json struct { Sender string `json:"sender" binding:"required"` Receiver string `json:"receiver" binding:"required"` Message string `json:"message" binding:"required"` } if c.Bind(&json) == nil { fmt.Printf("%+v\n", json) c.JSON(http.StatusOK, gin.H{}) } }) Authorized.POST("avatar", func(c *gin.Context) { uid := c.MustGet("uid").(uint) fmt.Printf("upload avatar uid=%d\n", uid) file, err := c.FormFile("file") if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } filename := file.Filename pos := strings.LastIndex(filename, ".") if pos == -1 { c.JSON(http.StatusBadRequest, gin.H{"error": "filename error"}) return } filename = uuid.New().String() + filename[pos:] if err := c.SaveUploadedFile(file, FileDirPath+filename); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } fmt.Println(filename) if err := SetAvatar(uid, filename); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"filename": filename}) }) Authorized.GET("profile/:name", func(c *gin.Context) { name := c.Param("name") // uid, err := strconv.Atoi(c.Param("uid")) // if err != nil { // c.JSON(http.StatusBadRequest, gin.H{"status": "bad request", "error": err.Error()}) // return // } uid, err := GetUID(name) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } if uid == 0 { c.JSON(http.StatusNotFound, gin.H{"error": "not found"}) return } profile, err := GetProfile(uid) if err != nil { c.JSON(ErrCode(err), gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"profile": profile}) }) Authorized.GET("file/:filename", func(c *gin.Context) { // uid := c.MustGet("uid").(uint) filename := c.Param("filename") // fmt.Printf("uid(%d) get avatar of id=%d\n", uid, id) // filename, err := GetAvatar(uint(id)) c.FileAttachment(FileDirPath+filename, filename) }) } // JWTAuthMiddleware 基于JWT的认证中间件 func JWTAuthMiddleware() func(c *gin.Context) { return func(c *gin.Context) { // 客户端携带Token有三种方式 1.放在请求头 2.放在请求体 3.放在URI // 这里假设Token放在Header的Authorization中,并使用Bearer开头 // 这里的具体实现方式要依据你的实际业务情况决定 authHeader := c.Request.Header.Get("Authorization") // fmt.Println(authHeader) if authHeader == "" { c.JSON(http.StatusBadRequest, gin.H{ "error": "请求头中auth为空", }) c.Abort() return } // 按空格分割 parts := strings.SplitN(authHeader, " ", 2) if !(len(parts) == 2 && parts[0] == "Bearer") { c.JSON(http.StatusBadRequest, gin.H{ "error": "请求头中auth格式有误", }) c.Abort() return } // parts[1]是获取到的tokenString,我们使用之前定义好的解析JWT的函数来解析它 mc, err := ParseToken(parts[1]) fmt.Printf("token=%+v\n", mc) if err != nil { c.JSON(http.StatusUnauthorized, gin.H{ "error": "无效的Token", }) c.Abort() return } // 将当前请求的username信息保存到请求的上下文c上 c.Set("username", mc.Username) c.Set("uid", mc.UID) fmt.Printf("username=%s uid=%d\n", mc.Username, mc.UID) c.Next() // 后续的处理函数可以用过c.Get("uid")来获取当前请求的用户信息 } } func homeHandler(c *gin.Context) { username := c.MustGet("username").(string) uid := c.MustGet("uid").(uint) c.JSON(http.StatusOK, gin.H{ "username": username, "uid": uid, }) }