package main import ( "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt" "io" "os" "strings" "videoplayer/dao" "videoplayer/handler" "videoplayer/proto" "videoplayer/worker" ) var signingKey = []byte(proto.TOKEN_SECRET) func main() { r := gin.Default() gin.SetMode(gin.ReleaseMode) err := dao.Init() if err != nil { panic("failed to connect database:" + err.Error()) } err = worker.InitRedis() if err != nil { panic("failed to connect redis:" + err.Error()) } r.Use(handler.CrosHandler()) r.Use(JWTAuthMiddleware()) // 使用 JWT 认证中间件 handler.SetUpVideoGroup(r) // Video handler.SetUpUserGroup(r) // User handler.SetUpDeviceGroup(r) // Device handler.SetUpIMGroup(r) // IM handler.SetUpCIDGroup(r) // CID,持续集成、部署 handler.SetUpToolGroup(r) // Tool r.Run(":8083") // listen and serve on 0.0.0.0:8083 defer dao.Close() defer worker.CloseRedis() } func init() { // 创建cid的目录 os.MkdirAll(proto.CID_BASE_DIR, os.ModePerm) os.MkdirAll(proto.CID_BASE_DIR+"script", os.ModePerm) os.MkdirAll(proto.CID_BASE_DIR+"workspace", os.ModePerm) } func writeLogger(c *gin.Context) { ip := c.ClientIP() method := c.Request.Method path := c.Request.URL.Path params := "" if method == "GET" { params = c.Request.URL.RawQuery } if method == "POST" && !strings.Contains(c.Request.URL.Path, "/upload") { params = c.Request.PostForm.Encode() if params == "" { // 请求体 bodyBytes, _ := io.ReadAll(c.Request.Body) c.Request.Body = io.NopCloser(strings.NewReader(string(bodyBytes))) // Write body back, so other handler can read it too params = string(bodyBytes) } } if strings.Contains(c.Request.URL.Path, "/upload") { params = "upload file" } go dao.InsertLogToDB(path, ip, method, params) } func JWTAuthMiddleware() gin.HandlerFunc { return func(c *gin.Context) { writeLogger(c) // 从请求头中获取 JWT 令牌 tokenString := c.Request.Header.Get("token") //请求方式为get时,从url中获取token if tokenString == "" { tokenString = c.Query("token") } //如果请求为login或register,则不需要验证token if strings.Contains(c.Request.URL.Path, "/login") || strings.Contains(c.Request.URL.Path, "/register") || strings.Contains(c.Request.URL.Path, "/uuid") || strings.Contains(c.Request.URL.Path, "/gqr") || strings.Contains(c.Request.URL.Path, "/cid/callback") { c.Next() return } if tokenString == "" { //c.AbortWithStatus(200) c.JSON(200, gin.H{ "message": "Unauthorized", "error": "token is empty", "code": proto.TokenIsNull, }) return } redisToken := worker.GetRedis(tokenString) if redisToken == "" { c.AbortWithStatus(200) c.JSON(200, gin.H{ "message": "NOT_LOGIN", "error": "server token is empty", "code": proto.TokenIsNull, }) return } // 解析 JWT 令牌 token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { return signingKey, nil }) // 验证令牌 if err != nil || !token.Valid { c.AbortWithStatus(200) c.JSON(200, gin.H{ "message": "NOT_LOGIN", "error": "Invalid token", "code": proto.TokenExpired, }) return } // 将用户信息添加到上下文中 c.Set("id", token.Claims.(jwt.MapClaims)["id"]) c.Set("username", token.Claims.(jwt.MapClaims)["username"]) // 继续处理请求 c.Next() } }