feat: enhance JWT handling by adding expiration parsing and logging in GetEndpoint

This commit is contained in:
王锦强
2025-04-02 13:14:29 +08:00
parent 0fd3ba7f61
commit 857f9055c8
2 changed files with 61 additions and 12 deletions

View File

@@ -89,13 +89,24 @@ func (c *Client) getEndpoint(ctx context.Context) (map[string]interface{}, error
// 获取新的端点信息 // 获取新的端点信息
endpoint, err := utils.GetEndpoint() endpoint, err := utils.GetEndpoint()
if err != nil { if err != nil {
log.Printf("获取认证信息失败: %v\n", err)
return nil, err return nil, err
} }
log.Printf("获取认证信息成功: %v\n", endpoint)
// 从 jwt 中解析出到期时间 exp
jwt := endpoint["t"].(string)
exp := utils.GetExp(jwt)
if exp == 0 {
return nil, errors.New("jwt 中缺少 exp 字段")
}
expTime := time.Unix(exp, 0)
log.Println("jwt 距到期时间:", expTime.Sub(time.Now()))
// 更新缓存 // 更新缓存
c.endpointMu.Lock() c.endpointMu.Lock()
c.endpoint = endpoint c.endpoint = endpoint
c.endpointExpiry = time.Now().Add(5 * time.Minute) c.endpointExpiry = expTime.Add(-1 * time.Minute) // 提前1分钟过期
c.endpointMu.Unlock() c.endpointMu.Unlock()
return endpoint, nil return endpoint, nil

View File

@@ -5,7 +5,6 @@ import (
"crypto/rand" "crypto/rand"
"crypto/sha256" "crypto/sha256"
"encoding/base64" "encoding/base64"
"encoding/hex"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@@ -33,26 +32,29 @@ const (
) )
func generateUserID() string { func generateUserID() string {
// 创建一个字节切片来存储随机数据 chars := "abcdef0123456789"
bytes := make([]byte, 8) // 8 字节 = 64 位 = 16 位十六进制字符串 result := make([]byte, 16)
_, err := rand.Read(bytes) for i := 0; i < 16; i++ {
if err != nil { randIndex := make([]byte, 1)
return "" if _, err := rand.Read(randIndex); err != nil {
return ""
}
result[i] = chars[randIndex[0]%uint8(len(chars))]
} }
// 将字节切片转换为十六进制字符串 return string(result)
userID := hex.EncodeToString(bytes)
return userID
} }
// GetEndpoint 获取语音合成服务的端点信息 // GetEndpoint 获取语音合成服务的端点信息
func GetEndpoint() (map[string]interface{}, error) { func GetEndpoint() (map[string]interface{}, error) {
signature := Sign(endpointURL) signature := Sign(endpointURL)
userId := generateUserID()
traceId := uuid.New().String()
headers := map[string]string{ headers := map[string]string{
"Accept-Language": "zh-Hans", "Accept-Language": "zh-Hans",
"X-ClientVersion": clientVersion, "X-ClientVersion": clientVersion,
"X-UserId": generateUserID(), "X-UserId": userId,
"X-HomeGeographicRegion": homeGeographicRegion, "X-HomeGeographicRegion": homeGeographicRegion,
"X-ClientTraceId": uuid.New().String(), "X-ClientTraceId": traceId,
"X-MT-Signature": signature, "X-MT-Signature": signature,
"User-Agent": userAgent, "User-Agent": userAgent,
"Content-Type": "application/json; charset=utf-8", "Content-Type": "application/json; charset=utf-8",
@@ -68,13 +70,22 @@ func GetEndpoint() (map[string]interface{}, error) {
req.Header.Set(k, v) req.Header.Set(k, v)
} }
headerJson, err := json.Marshal(&headers)
fmt.Printf("GetEndpoint -> url: %s, headers: %v\n", endpointURL, string(headerJson))
resp, err := client.Do(req) resp, err := client.Do(req)
if err != nil { if err != nil {
log.Error("failed to do request: ", err) log.Error("failed to do request: ", err)
return nil, err return nil, err
} }
defer resp.Body.Close() defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
log.Error("failed to get endpoint, status code: ", resp.StatusCode)
return nil, fmt.Errorf("failed to get endpoint, status code: %d", resp.StatusCode)
}
var result map[string]interface{} var result map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&result) err = json.NewDecoder(resp.Body).Decode(&result)
if err != nil { if err != nil {
@@ -183,3 +194,30 @@ func JoinURL(baseURL, relativePath string) (string, error) {
return base.ResolveReference(rel).String(), nil return base.ResolveReference(rel).String(), nil
} }
func GetExp(s string) int64 {
// 解析 JWT
parts := strings.Split(s, ".")
if len(parts) != 3 {
return 0
}
// 解码负载部分
payload, err := base64.RawURLEncoding.DecodeString(parts[1])
if err != nil {
return 0
}
// 解析 JSON
var data map[string]interface{}
if err := json.Unmarshal(payload, &data); err != nil {
return 0
}
exp, ok := data["exp"].(float64)
if !ok {
return 0
}
return int64(exp)
}