diff --git a/Dockerfile b/Dockerfile index 6651e58..099cba4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,11 @@ # 第一阶段:使用最新Go版本构建 -FROM golang:1.24 AS builder +FROM docker.1ms.run/golang:1.24 AS builder WORKDIR /app +ENV GOPROXY=https://goproxy.cn,direct + + # 复制go.mod和go.sum以缓存依赖 COPY go.mod go.sum ./ RUN go mod download @@ -27,4 +30,4 @@ WORKDIR /home/videoplayer EXPOSE 8083 # 运行应用 -CMD ["./videoplayer"] +CMD ["./videoplayer"] \ No newline at end of file diff --git a/main.go b/main.go index f2e2886..a112293 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( "encoding/json" + "errors" "fmt" "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt" @@ -100,29 +101,23 @@ func JWTAuthMiddleware() gin.HandlerFunc { } // 从请求头中获取 JWT 令牌 tokenString := c.Request.Header.Get("token") - //请求方式为get时,从url中获取token if tokenString == "" { tokenString = c.Query("token") } - //如果请求为login或register,则不需要验证token - //for k, _ := range proto.Url_map { - // if strings.Contains(c.Request.URL.Path, k) { - // c.Next() - // return - // } - //} - if proto.Url_map[c.Request.URL.Path] == true { //查看是否在不需要token的url中 - c.Next() - return + for k, _ := range proto.Url_map { + if strings.Contains(c.Request.URL.Path, k) { + log.Println("need not check token:", c.Request.URL.Path) + c.Next() + return + } } + //if proto.Url_map[c.Request.URL.Path] == true { //查看是否在不需要token的url中 + // c.Next() + // return + //} if tokenString == "" { - //c.AbortWithStatus(200) - c.JSON(200, gin.H{ - "message": "Unauthorized", - "error": "token is empty", - "code": proto.TokenIsNull, - }) + c.AbortWithStatusJSON(http.StatusOK, gin.H{"message": "unauthorized", "error": "token is empty", "code": proto.TokenIsNull}) return } if proto.Config.TOKEN_USE_REDIS { @@ -132,7 +127,6 @@ func JWTAuthMiddleware() gin.HandlerFunc { return } } - //查看token是否在超级token中 if worker.IsContainSet("super_permission_tokens", tokenString) { sId := c.Request.Header.Get("super_id") @@ -147,40 +141,52 @@ func JWTAuthMiddleware() gin.HandlerFunc { idFloat64 := float64(id) //查看s_id类型 c.Set("id", idFloat64) + c.Set("user_id", id) c.Next() return } // 使用加密secret 解析 JWT 令牌 - token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { + //token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { + // return proto.SigningKey, nil + //}) + token, err := jwt.Parse(tokenString, func(t *jwt.Token) (interface{}, error) { + // 验证签名算法 + if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok { + return nil, jwt.ErrSignatureInvalid + } return proto.SigningKey, nil }) - - // 验证令牌 - if err != nil || !token.Valid { - c.AbortWithStatusJSON(http.StatusOK, gin.H{ - "message": "NOT_LOGIN", - "error": "Invalid token", - "code": proto.TokenExpired, - }) - return + // 错误处理 + if err != nil { + var ve *jwt.ValidationError + if errors.As(err, &ve) { + switch { + case ve.Errors&jwt.ValidationErrorMalformed != 0: + c.AbortWithStatusJSON(http.StatusOK, gin.H{"error": "Malformed token:" + err.Error(), "code": proto.TokenInvalid}) + case ve.Errors&jwt.ValidationErrorExpired != 0: + c.AbortWithStatusJSON(http.StatusOK, gin.H{"error": "Token expired:" + err.Error(), "code": proto.TokenExpired}) + case ve.Errors&jwt.ValidationErrorNotValidYet != 0: + c.AbortWithStatusJSON(http.StatusOK, gin.H{"error": "Token not active yet:" + err.Error(), "code": proto.TokenInvalid}) + default: + c.AbortWithStatusJSON(http.StatusOK, gin.H{"error": "Invalid token:" + err.Error(), "code": proto.TokenInvalid}) + } + return + } } // 将用户信息添加到上下文中 - c.Set("id", token.Claims.(jwt.MapClaims)["id"]) - c.Set("username", token.Claims.(jwt.MapClaims)["username"]) + id := token.Claims.(jwt.MapClaims)["id"] + c.Set("id", id) + c.Set("user_id", int(id.(float64))) - if UserFuncIntercept(int(token.Claims.(jwt.MapClaims)["id"].(float64)), c.Request.URL.Path) { - c.AbortWithStatusJSON(http.StatusOK, gin.H{ - "message": "no function permission", - "error": "no permission", - "code": proto.NoPermission, - }) + if UserFuncIntercept(int(id.(float64)), c.Request.URL.Path) { + c.AbortWithStatusJSON(http.StatusOK, gin.H{"message": "unauthorized", "error": "no function permission", "code": proto.NoPermission}) return } - // 继续处理请求 c.Next() + //log.Println("JWT token is valid, user ID:", token.Claims.(jwt.MapClaims)["id"], " path:", c.Request.URL.Path) } }