| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 |
- package middleware
- import (
- "net/http"
- "strings"
- "github.com/celestia-trace/backend/config"
- "github.com/gin-gonic/gin"
- "github.com/golang-jwt/jwt/v5"
- )
- // Auth middleware validates JWT token
- func Auth(cfg *config.Config) gin.HandlerFunc {
- return func(c *gin.Context) {
- authHeader := c.GetHeader("Authorization")
- if authHeader == "" {
- c.JSON(http.StatusUnauthorized, gin.H{"code": 401, "message": "missing authorization header"})
- c.Abort()
- return
- }
- parts := strings.Split(authHeader, " ")
- if len(parts) != 2 || parts[0] != "Bearer" {
- c.JSON(http.StatusUnauthorized, gin.H{"code": 401, "message": "invalid authorization header format"})
- c.Abort()
- return
- }
- tokenString := parts[1]
- token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
- if token.Method.Alg() != jwt.SigningMethodHS256.Alg() {
- return nil, jwt.ErrSignatureInvalid
- }
- return []byte(cfg.JWTSecret), nil
- }, jwt.WithIssuer("celestia-trace"), jwt.WithExpirationRequired())
- if err != nil || !token.Valid {
- c.JSON(http.StatusUnauthorized, gin.H{"code": 401, "message": "invalid token"})
- c.Abort()
- return
- }
- claims, ok := token.Claims.(jwt.MapClaims)
- if !ok {
- c.JSON(http.StatusUnauthorized, gin.H{"code": 401, "message": "invalid token claims"})
- c.Abort()
- return
- }
- userID, ok := claims["sub"].(string)
- if !ok {
- c.JSON(http.StatusUnauthorized, gin.H{"code": 401, "message": "invalid subject in token"})
- c.Abort()
- return
- }
- // Set user ID for downstream handlers
- c.Set("userID", userID)
- if sessionID, ok := claims["sid"].(string); ok {
- c.Set("sessionID", sessionID)
- }
- c.Next()
- }
- }
|