package token import ( "fmt" "log" "os" "strconv" "strings" "time" //jwt "github.com/dgrijalva/jwt-go" "github.com/gin-gonic/gin" jwt "github.com/golang-jwt/jwt/v5" ) func GenerateToken(user_id uint) (string, error) { token_lifespan, err := strconv.Atoi(os.Getenv("TOKEN_HOUR_LIFESPAN")) if err != nil { log.Printf("GenerateToken Error getting env value TOKEN_HOUR_LIFESPAN\n") return "", err } claims := jwt.MapClaims{} claims["authorized"] = true claims["user_id"] = user_id claims["exp"] = time.Now().Add(time.Hour * time.Duration(token_lifespan)).Unix() // https://pkg.go.dev/github.com/golang-jwt/jwt/v5#New token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) return token.SignedString([]byte(os.Getenv("API_SECRET"))) } func TokenValid(c *gin.Context) error { tokenString := ExtractToken(c) _, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) } // This code says signature is invalid if we return an empty []byte but I don't know why return []byte(os.Getenv("API_SECRET")), nil }) if err != nil { return err } return nil } func ExtractToken(c *gin.Context) string { token := c.Query("token") if token != "" { return token } bearerToken := c.Request.Header.Get("Authorization") //log.Printf("ExtractToken extracted token '%v'\n", bearerToken) if len(strings.Split(bearerToken, " ")) == 2 { return strings.Split(bearerToken, " ")[1] } return "" } func ExtractTokenID(c *gin.Context) (uint, error) { tokenString := ExtractToken(c) token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) } // Why return the secret?? Code doesn't work if we don't return the secret return []byte(os.Getenv("API_SECRET")), nil }) if err != nil { log.Printf("ExtractTokenID error parsing token : '%s'\n", err) return 0, err } claims, ok := token.Claims.(jwt.MapClaims) if ok && token.Valid { uid, err := strconv.ParseUint(fmt.Sprintf("%.0f", claims["user_id"]), 10, 32) if err != nil { log.Printf("ExtractTokenID checking token valid : '%s'\n", err) return 0, err } return uint(uid), nil } log.Printf("ExtractTokenID unknown error\n") return 0, nil }