加密
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

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
}