gcx/backend/services/chain-indexer/internal/interface/http/middleware/auth.go

73 lines
1.7 KiB
Go

package middleware
import (
"net/http"
"os"
"strings"
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt/v5"
)
// JWTAuth validates the JWT token in the Authorization header.
func JWTAuth() gin.HandlerFunc {
secret := []byte(getEnv("JWT_ACCESS_SECRET", "dev-access-secret"))
return func(c *gin.Context) {
authHeader := c.GetHeader("Authorization")
if authHeader == "" {
c.JSON(http.StatusUnauthorized, gin.H{"code": -1, "message": "Missing authorization header"})
c.Abort()
return
}
parts := strings.SplitN(authHeader, " ", 2)
if len(parts) != 2 || parts[0] != "Bearer" {
c.JSON(http.StatusUnauthorized, gin.H{"code": -1, "message": "Invalid authorization format"})
c.Abort()
return
}
token, err := jwt.Parse(parts[1], func(t *jwt.Token) (interface{}, error) {
return secret, nil
})
if err != nil || !token.Valid {
c.JSON(http.StatusUnauthorized, gin.H{"code": -1, "message": "Invalid token"})
c.Abort()
return
}
claims, ok := token.Claims.(jwt.MapClaims)
if !ok {
c.JSON(http.StatusUnauthorized, gin.H{"code": -1, "message": "Invalid claims"})
c.Abort()
return
}
c.Set("userId", claims["sub"])
c.Set("role", claims["role"])
c.Next()
}
}
// RequireAdmin checks that the authenticated user has an admin role.
func RequireAdmin() gin.HandlerFunc {
return func(c *gin.Context) {
role, _ := c.Get("role")
roleStr, _ := role.(string)
if roleStr != "admin" && roleStr != "super_admin" {
c.JSON(http.StatusForbidden, gin.H{"code": -1, "message": "Admin access required"})
c.Abort()
return
}
c.Next()
}
}
func getEnv(key, fallback string) string {
if v := os.Getenv(key); v != "" {
return v
}
return fallback
}