package auth import ( "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt/v4" "net/http" "strings" "time" ) var JWTSecret = []byte("your-secret-key") // 在實際使用時應該從環境變量獲取 type Claims struct { Username string `json:"username"` jwt.StandardClaims } // 生成 JWT token func GenerateToken(username string) (string, error) { claims := Claims{ username, jwt.StandardClaims{ ExpiresAt: time.Now().Add(24 * time.Hour).Unix(), IssuedAt: time.Now().Unix(), }, } token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) return token.SignedString(JWTSecret) } // JWT 認證中間件 func JWTAuthMiddleware() gin.HandlerFunc { return func(c *gin.Context) { authHeader := c.GetHeader("Authorization") if authHeader == "" { c.JSON(http.StatusUnauthorized, gin.H{"error": "Authorization header is required"}) c.Abort() return } parts := strings.SplitN(authHeader, " ", 2) if !(len(parts) == 2 && parts[0] == "Bearer") { c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid authorization format"}) c.Abort() return } claims := &Claims{} token, err := jwt.ParseWithClaims(parts[1], claims, func(token *jwt.Token) (interface{}, error) { return JWTSecret, nil }) if err != nil || !token.Valid { c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid or expired token"}) c.Abort() return } c.Set("username", claims.Username) c.Next() } }