蛋蛋星球-客户端
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

87 lines
2.3 KiB

  1. package auth
  2. import (
  3. "applet/app/utils/cache"
  4. "errors"
  5. "fmt"
  6. "github.com/dgrijalva/jwt-go"
  7. "time"
  8. )
  9. // GenToken 生成JWT
  10. func GenToken(uid int64) (string, error) {
  11. // 创建一个我们自己的声明
  12. c := JWTUser{
  13. Uid: uid,
  14. StandardClaims: jwt.StandardClaims{
  15. ExpiresAt: time.Now().Add(TokenExpireDuration).Unix(), // 过期时间
  16. Issuer: "egg_app", // 签发人
  17. },
  18. }
  19. // 使用指定的签名方法创建签名对象
  20. tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, c)
  21. // 使用指定的secret签名并获得完整的编码后的字符串token
  22. token, err := tokenClaims.SignedString(Secret)
  23. if err != nil {
  24. return "", err
  25. }
  26. // 缓存token
  27. cacheKey := fmt.Sprintf(TokenKey, uid)
  28. _, err = cache.SetEx(cacheKey, token, TokenCacheTime)
  29. if err != nil {
  30. return "", err
  31. }
  32. return token, nil
  33. }
  34. // ParseToken 解析JWT
  35. func ParseToken(tokenString string) (*JWTUser, string, error) {
  36. // 解析token
  37. token, err := jwt.ParseWithClaims(tokenString, &JWTUser{}, func(token *jwt.Token) (i interface{}, err error) {
  38. return Secret, nil
  39. })
  40. if err != nil {
  41. return nil, "", err
  42. }
  43. if claims, ok := token.Claims.(*JWTUser); ok && token.Valid { // 校验token正确性
  44. if claims.StandardClaims.ExpiresAt < time.Now().Unix() { // 校验token时效性
  45. return nil, "", errors.New("token is expired")
  46. }
  47. //TODO::单设备验证
  48. cacheKey := fmt.Sprintf(TokenKey, claims.Uid)
  49. cJwt, err1 := cache.GetString(cacheKey)
  50. if err1 != nil {
  51. return nil, "", err1
  52. }
  53. if cJwt != tokenString && cJwt != "" {
  54. fmt.Println(cJwt)
  55. fmt.Println(tokenString)
  56. return nil, "", errors.New("token expired")
  57. }
  58. // TODO::判断Token快过期,就创建新的token(7天)
  59. if !claims.VerifyExpiresAt(time.Now().Add(time.Hour*24*7).Unix(), false) {
  60. newToken, _ := GenToken(claims.Uid)
  61. return claims, newToken, nil
  62. }
  63. // TODO::判断缓存是否为空,若为空则填补
  64. if cJwt == "" {
  65. _, err = cache.SetEx(cacheKey, token, CalculateSecondsUntilExpiry(time.Unix(claims.ExpiresAt, 0)))
  66. if err != nil {
  67. return nil, "", err
  68. }
  69. }
  70. return claims, "", err
  71. }
  72. return nil, "", errors.New("invalid token")
  73. }
  74. // CalculateSecondsUntilExpiry 计算 Token 距离现在的过期时间还有多少秒
  75. func CalculateSecondsUntilExpiry(expiryTime time.Time) int {
  76. return int(expiryTime.Sub(time.Now()).Seconds())
  77. }