service.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. package jwtutils
  2. import (
  3. "time"
  4. "git.linuxforward.com/byom/byom-core/logger"
  5. "github.com/golang-jwt/jwt/v5"
  6. "github.com/sirupsen/logrus"
  7. )
  8. // Service is the service that provides JWT functionalities
  9. // Custom payload can be added to the token
  10. type Service struct {
  11. secret string
  12. logger *logrus.Entry
  13. }
  14. func NewService(secret string) *Service {
  15. return &Service{
  16. secret: secret,
  17. logger: logger.NewLogger("jwt"),
  18. }
  19. }
  20. func (s *Service) GenerateToken(email, role string) (string, error) {
  21. now := time.Now()
  22. claims := jwt.MapClaims{
  23. "sub": email,
  24. "exp": now.Add(24 * time.Hour).Unix(),
  25. "iat": now.Unix(),
  26. "role": role,
  27. }
  28. token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
  29. signedToken, err := token.SignedString([]byte(s.secret))
  30. if err != nil {
  31. s.logger.WithError(err).Error("failed to sign token")
  32. return "", err
  33. }
  34. return signedToken, nil
  35. }
  36. func (s *Service) ValidateToken(token string) (jwt.MapClaims, error) {
  37. parsedToken, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {
  38. return []byte(s.secret), nil
  39. })
  40. if err != nil {
  41. s.logger.WithError(err).Error("failed to parse token")
  42. return nil, err
  43. }
  44. claims, ok := parsedToken.Claims.(jwt.MapClaims)
  45. if !ok || !parsedToken.Valid {
  46. return nil, jwt.ErrSignatureInvalid
  47. }
  48. if exp, ok := claims["exp"].(float64); ok {
  49. if time.Now().Unix() > int64(exp) {
  50. return nil, jwt.ErrTokenExpired
  51. }
  52. }
  53. return claims, nil
  54. }
  55. func (s *Service) ExtractEmailFromClaims(claims jwt.MapClaims) string {
  56. email, ok := claims["sub"].(string)
  57. if !ok {
  58. return ""
  59. }
  60. return email
  61. }