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
|
|
}
|