// Package token 提供极简 HS256 JWT 生成与校验(仅依赖标准库)。 // 后台管理用于登录态签发与中间件校验;小程序登录态请见各小程序 service。 package token import ( "crypto/hmac" "crypto/sha256" "encoding/base64" "encoding/json" "errors" "strings" "time" ) var b64 = base64.RawURLEncoding // Claims 是后台 JWT 的载荷。 type Claims struct { AdminID string `json:"admin_id"` Exp int64 `json:"exp"` } const header = `{"alg":"HS256","typ":"JWT"}` // Generate 签发一个 HS256 token。 func Generate(secret, adminID string, ttl time.Duration) (string, error) { payload, err := json.Marshal(Claims{AdminID: adminID, Exp: time.Now().Add(ttl).Unix()}) if err != nil { return "", err } signingInput := b64.EncodeToString([]byte(header)) + "." + b64.EncodeToString(payload) return signingInput + "." + sign(secret, signingInput), nil } // Parse 校验 token 签名与有效期,返回 Claims。 func Parse(secret, tokenStr string) (*Claims, error) { parts := strings.Split(tokenStr, ".") if len(parts) != 3 { return nil, errors.New("invalid token format") } expected := sign(secret, parts[0]+"."+parts[1]) if !hmac.Equal([]byte(expected), []byte(parts[2])) { return nil, errors.New("bad signature") } raw, err := b64.DecodeString(parts[1]) if err != nil { return nil, err } var claims Claims if err := json.Unmarshal(raw, &claims); err != nil { return nil, err } if claims.Exp < time.Now().Unix() { return nil, errors.New("token expired") } return &claims, nil } func sign(secret, input string) string { mac := hmac.New(sha256.New, []byte(secret)) mac.Write([]byte(input)) return b64.EncodeToString(mac.Sum(nil)) }