jwt.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. package controller
  2. import (
  3. "fmt"
  4. "net/http"
  5. "strconv"
  6. "strings"
  7. "time"
  8. "woord-core-service/global"
  9. "github.com/gin-gonic/gin"
  10. "github.com/golang-jwt/jwt/v4"
  11. )
  12. const AuthUserKey = "user"
  13. var (
  14. ErrNotLoggedIn = fmt.Errorf("请先登录")
  15. ErrInvalidToken = fmt.Errorf("登录失效,请重新登录")
  16. )
  17. // 根据用户 ID 生成 JWT
  18. func newToken(userID uint) (string, error) {
  19. token := jwt.NewWithClaims(jwt.SigningMethodHS256, &jwt.RegisteredClaims{
  20. Subject: strconv.FormatUint(uint64(userID), 10),
  21. ExpiresAt: jwt.NewNumericDate(time.Now().Add(720 * time.Hour)),
  22. })
  23. return token.SignedString(global.SecretKey)
  24. }
  25. // 根据 JWT 解析用户 ID
  26. func parseToken(tokenString string) (uint, error) {
  27. token, err := jwt.ParseWithClaims(tokenString, &jwt.RegisteredClaims{}, func(token *jwt.Token) (any, error) {
  28. // 检查签名方法是否正确
  29. if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
  30. return nil, fmt.Errorf("unexpected signing method: %s", token.Method.Alg())
  31. }
  32. return global.SecretKey, nil
  33. })
  34. if claims, ok := token.Claims.(*jwt.RegisteredClaims); ok && token.Valid {
  35. userID, err := strconv.ParseUint(claims.Subject, 10, 0)
  36. return uint(userID), err
  37. }
  38. return 0, err
  39. }
  40. // JWT 认证中间件
  41. func JWTAuth() gin.HandlerFunc {
  42. return func(c *gin.Context) {
  43. // 获取 Authorization 请求头
  44. auth := strings.Split(c.GetHeader("Authorization"), " ")
  45. if len(auth) < 2 || auth[0] != "Bearer" {
  46. respondError(c, http.StatusUnauthorized, ErrNotLoggedIn)
  47. c.Abort()
  48. return
  49. }
  50. // 解析 JWT
  51. userID, err := parseToken(auth[1])
  52. if err != nil {
  53. respondError(c, http.StatusUnauthorized, ErrInvalidToken)
  54. c.Abort()
  55. return
  56. }
  57. // 将用户 ID 保存在上下文中
  58. c.Set(AuthUserKey, userID)
  59. }
  60. }