jwt.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. package utils
  2. import (
  3. "fmt"
  4. "os"
  5. "strconv"
  6. "time"
  7. "ems-backend/models"
  8. "github.com/golang-jwt/jwt/v5"
  9. )
  10. type Claims struct {
  11. Username string `json:"username"`
  12. UserID string `json:"userId"`
  13. jwt.RegisteredClaims
  14. }
  15. func jwtSecret() []byte {
  16. secret := os.Getenv("JWT_SECRET")
  17. if secret == "" {
  18. secret = "ems-dev-secret"
  19. }
  20. return []byte(secret)
  21. }
  22. func tokenExpireHours() int {
  23. expireStr := os.Getenv("JWT_EXPIRE_HOURS")
  24. if expireStr == "" {
  25. return 24
  26. }
  27. expireHours, err := strconv.Atoi(expireStr)
  28. if err != nil || expireHours <= 0 {
  29. return 24
  30. }
  31. return expireHours
  32. }
  33. func GenerateToken(user models.User) (string, error) {
  34. now := time.Now()
  35. expiresAt := now.Add(time.Duration(tokenExpireHours()) * time.Hour)
  36. claims := Claims{
  37. Username: user.Username,
  38. UserID: user.ID.String(),
  39. RegisteredClaims: jwt.RegisteredClaims{
  40. IssuedAt: jwt.NewNumericDate(now),
  41. ExpiresAt: jwt.NewNumericDate(expiresAt),
  42. },
  43. }
  44. token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
  45. return token.SignedString(jwtSecret())
  46. }
  47. func ParseToken(tokenString string) (*Claims, error) {
  48. token, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(t *jwt.Token) (interface{}, error) {
  49. if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
  50. return nil, fmt.Errorf("unexpected signing method")
  51. }
  52. return jwtSecret(), nil
  53. })
  54. if err != nil {
  55. return nil, err
  56. }
  57. claims, ok := token.Claims.(*Claims)
  58. if !ok || !token.Valid {
  59. return nil, fmt.Errorf("invalid token")
  60. }
  61. return claims, nil
  62. }