package crypter import ( "errors" "fmt" "log" "strconv" "time" "github.com/dgrijalva/jwt-go" ) //JWT = JSON WEB TOKEN 是一个开放标准,用于作为json对象,在各个地方安全的传输信息 //此信息可以被验证和信任 func CreateJwtToken(client_id, client_secret string) (string, error) { // Define the secret key used for signing the token secretKey := []byte(client_secret) // Create a new token with claims token := jwt.New(jwt.SigningMethodHS256) claims := token.Claims.(jwt.MapClaims) // Set the issuer, issued at, and JWT ID claims claims["iss"] = client_id claims["iat"] = time.Now().Unix() claims["jti"] = strconv.Itoa(time.Now().Nanosecond()) // log.Println(claims) // Sign the token with the secret key tokenString, err := token.SignedString(secretKey) if err != nil { log.Println("Error signing token:", err) return "", err } return tokenString, nil } func VerifyToken(tokenString string, client_id, client_secret string, expire int64) (bool, error) { token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { return []byte(client_secret), nil }) // log.Println(token, token.Claims, err) if token.Valid { claims := token.Claims.(jwt.MapClaims) if client_id != claims["iss"] { return false, errors.New("invalid client_id") } iat := ToInt64(claims["iat"]) now := time.Now().Unix() log.Println(iat, now) if now-iat > expire || iat-now > expire { return false, errors.New("invalid time") } return true, nil } else if ve, ok := err.(*jwt.ValidationError); ok { if ve.Errors&jwt.ValidationErrorMalformed != 0 { return false, errors.New("Malformed token") } else if ve.Errors&(jwt.ValidationErrorExpired|jwt.ValidationErrorNotValidYet) != 0 { return false, errors.New("Expired token") } else { return false, errors.New("Invalid token") } } else { return false, errors.New("Invalid token") } } func CheckJwtToken(tokenString string, client_secret string) (jwt.MapClaims, bool, error) { // Define the secret key used for verifying the token secretKey := []byte(client_secret) // jwt.DecodeSegment() // Parse the token token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { // Check the signing method if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"]) } return secretKey, nil }) // Verify the token if err != nil { log.Println("Error parsing token:", err) return nil, false, err } if token.Valid { // log.Println("Token is valid!") // Access the claims claims := token.Claims.(jwt.MapClaims) // log.Println("Issuer:", claims["iss"]) // log.Println("Issued At:", claims["iat"]) // log.Println("JWT ID:", claims["jti"]) return claims, true, nil } return nil, false, nil } func ToInt64(inter interface{}) int64 { var value int64 switch inter.(type) { case string: value, _ = strconv.ParseInt(inter.(string), 10, 64) case int: value = int64(inter.(int)) case int64: value = inter.(int64) case float64: value_int, _ := strconv.Atoi(fmt.Sprintf("%1.0f", inter)) value = int64(value_int) case nil: value = 0 case interface{}: if _, ok := inter.(int64); !ok { value = inter.(int64) } default: log.Println("参数值类型错误", inter, "not in string|int|float64|interface|int64") } return value }