auth.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. package middleware
  2. import (
  3. "net/http"
  4. "strings"
  5. "github.com/celestia-trace/backend/config"
  6. "github.com/gin-gonic/gin"
  7. "github.com/golang-jwt/jwt/v5"
  8. )
  9. // Auth middleware validates JWT token
  10. func Auth(cfg *config.Config) gin.HandlerFunc {
  11. return func(c *gin.Context) {
  12. authHeader := c.GetHeader("Authorization")
  13. if authHeader == "" {
  14. if queryToken := c.Query("token"); queryToken != "" {
  15. authHeader = "Bearer " + queryToken
  16. } else {
  17. c.JSON(http.StatusUnauthorized, gin.H{"code": 401, "message": "missing authorization header"})
  18. c.Abort()
  19. return
  20. }
  21. }
  22. parts := strings.Split(authHeader, " ")
  23. if len(parts) != 2 || parts[0] != "Bearer" {
  24. c.JSON(http.StatusUnauthorized, gin.H{"code": 401, "message": "invalid authorization header format"})
  25. c.Abort()
  26. return
  27. }
  28. tokenString := parts[1]
  29. token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
  30. if token.Method.Alg() != jwt.SigningMethodHS256.Alg() {
  31. return nil, jwt.ErrSignatureInvalid
  32. }
  33. return []byte(cfg.JWTSecret), nil
  34. }, jwt.WithIssuer("celestia-trace"), jwt.WithExpirationRequired())
  35. if err != nil || !token.Valid {
  36. c.JSON(http.StatusUnauthorized, gin.H{"code": 401, "message": "invalid token"})
  37. c.Abort()
  38. return
  39. }
  40. claims, ok := token.Claims.(jwt.MapClaims)
  41. if !ok {
  42. c.JSON(http.StatusUnauthorized, gin.H{"code": 401, "message": "invalid token claims"})
  43. c.Abort()
  44. return
  45. }
  46. userID, ok := claims["sub"].(string)
  47. if !ok {
  48. c.JSON(http.StatusUnauthorized, gin.H{"code": 401, "message": "invalid subject in token"})
  49. c.Abort()
  50. return
  51. }
  52. // Set user ID for downstream handlers
  53. c.Set("userID", userID)
  54. if sessionID, ok := claims["sid"].(string); ok {
  55. c.Set("sessionID", sessionID)
  56. }
  57. c.Next()
  58. }
  59. }