加密
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
3.3 KiB

  1. package crypter
  2. import (
  3. "errors"
  4. "fmt"
  5. "log"
  6. "strconv"
  7. "time"
  8. "github.com/dgrijalva/jwt-go"
  9. )
  10. //JWT = JSON WEB TOKEN 是一个开放标准,用于作为json对象,在各个地方安全的传输信息
  11. //此信息可以被验证和信任
  12. func CreateJwtToken(client_id, client_secret string) (string, error) {
  13. // Define the secret key used for signing the token
  14. secretKey := []byte(client_secret)
  15. // Create a new token with claims
  16. token := jwt.New(jwt.SigningMethodHS256)
  17. claims := token.Claims.(jwt.MapClaims)
  18. // Set the issuer, issued at, and JWT ID claims
  19. claims["iss"] = client_id
  20. claims["iat"] = time.Now().Unix()
  21. claims["jti"] = strconv.Itoa(time.Now().Nanosecond())
  22. // log.Println(claims)
  23. // Sign the token with the secret key
  24. tokenString, err := token.SignedString(secretKey)
  25. if err != nil {
  26. log.Println("Error signing token:", err)
  27. return "", err
  28. }
  29. return tokenString, nil
  30. }
  31. func VerifyToken(tokenString string, client_id, client_secret string, expire int64) (bool, error) {
  32. token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
  33. return []byte(client_secret), nil
  34. })
  35. // log.Println(token, token.Claims, err)
  36. if token.Valid {
  37. claims := token.Claims.(jwt.MapClaims)
  38. if client_id != claims["iss"] {
  39. return false, errors.New("invalid client_id")
  40. }
  41. iat := ToInt64(claims["iat"])
  42. now := time.Now().Unix()
  43. log.Println(iat, now)
  44. if now-iat > expire || iat-now > expire {
  45. return false, errors.New("invalid time")
  46. }
  47. return true, nil
  48. } else if ve, ok := err.(*jwt.ValidationError); ok {
  49. if ve.Errors&jwt.ValidationErrorMalformed != 0 {
  50. return false, errors.New("Malformed token")
  51. } else if ve.Errors&(jwt.ValidationErrorExpired|jwt.ValidationErrorNotValidYet) != 0 {
  52. return false, errors.New("Expired token")
  53. } else {
  54. return false, errors.New("Invalid token")
  55. }
  56. } else {
  57. return false, errors.New("Invalid token")
  58. }
  59. }
  60. func CheckJwtToken(tokenString string, client_secret string) (jwt.MapClaims, bool, error) {
  61. // Define the secret key used for verifying the token
  62. secretKey := []byte(client_secret)
  63. // jwt.DecodeSegment()
  64. // Parse the token
  65. token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
  66. // Check the signing method
  67. if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
  68. return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
  69. }
  70. return secretKey, nil
  71. })
  72. // Verify the token
  73. if err != nil {
  74. log.Println("Error parsing token:", err)
  75. return nil, false, err
  76. }
  77. if token.Valid {
  78. // log.Println("Token is valid!")
  79. // Access the claims
  80. claims := token.Claims.(jwt.MapClaims)
  81. // log.Println("Issuer:", claims["iss"])
  82. // log.Println("Issued At:", claims["iat"])
  83. // log.Println("JWT ID:", claims["jti"])
  84. return claims, true, nil
  85. }
  86. return nil, false, nil
  87. }
  88. func ToInt64(inter interface{}) int64 {
  89. var value int64
  90. switch inter.(type) {
  91. case string:
  92. value, _ = strconv.ParseInt(inter.(string), 10, 64)
  93. case int:
  94. value = int64(inter.(int))
  95. case int64:
  96. value = inter.(int64)
  97. case float64:
  98. value_int, _ := strconv.Atoi(fmt.Sprintf("%1.0f", inter))
  99. value = int64(value_int)
  100. case nil:
  101. value = 0
  102. case interface{}:
  103. if _, ok := inter.(int64); !ok {
  104. value = inter.(int64)
  105. }
  106. default:
  107. log.Println("参数值类型错误", inter, "not in string|int|float64|interface|int64")
  108. }
  109. return value
  110. }