init: 自 zomaintain/backend/zonat 平移独立成库; module path 改为 git.zeroonesoft.cn/golib/zonat; 内部 import 同步重写
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
// jwt.go agent 登录令牌的 JWT 校验与签发(HS256)。
|
||||
// 正式部署由签发方(如 cloud)生成 token 下发给各隧道;节点只做校验。
|
||||
// SignToken 供 cmd/node -print-token(运维手工签发)与测试使用。
|
||||
package node
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
)
|
||||
|
||||
// verifyToken 校验 agent 登录 JWT:
|
||||
// - HS256/384/512 签名(显式白名单,拒绝 none 与其它算法)
|
||||
// - 必须带 exp 且未过期
|
||||
// - 若带 agentId 或 sub claim,则必须与登录 AgentId 一致(防跨 agent 冒用)
|
||||
func verifyToken(token, secret, agentId string) error {
|
||||
if secret == "" {
|
||||
return errors.New("节点未配置JWT密钥")
|
||||
}
|
||||
parsed, err := jwt.Parse(token, func(t *jwt.Token) (any, error) {
|
||||
if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||
return nil, fmt.Errorf("签名算法不允许:%v", t.Header["alg"])
|
||||
}
|
||||
return []byte(secret), nil
|
||||
}, jwt.WithValidMethods([]string{
|
||||
jwt.SigningMethodHS256.Alg(),
|
||||
jwt.SigningMethodHS384.Alg(),
|
||||
jwt.SigningMethodHS512.Alg(),
|
||||
}), jwt.WithExpirationRequired())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
claims, ok := parsed.Claims.(jwt.MapClaims)
|
||||
if !ok {
|
||||
return errors.New("claims类型错误")
|
||||
}
|
||||
for _, k := range []string{"agentId", "sub"} {
|
||||
if v, ok := claims[k].(string); ok && v != "" && v != agentId {
|
||||
return fmt.Errorf("token %s 与登录agentId不一致", k)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SignToken 用节点密钥签发一张 agent 登录 JWT。
|
||||
// ttl<=0 会得到立即过期的 token(仅测试构造过期样例时有意义)。
|
||||
func SignToken(secret, agentId string, ttl time.Duration) (string, error) {
|
||||
if secret == "" {
|
||||
return "", errors.New("未配置JWT密钥")
|
||||
}
|
||||
now := time.Now()
|
||||
claims := jwt.MapClaims{
|
||||
"agentId": agentId,
|
||||
"iat": now.Unix(),
|
||||
"exp": now.Add(ttl).Unix(),
|
||||
}
|
||||
return jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString([]byte(secret))
|
||||
}
|
||||
Reference in New Issue
Block a user