feat: v2.0.0 完整代码优化升级

🔴 高优先级 (6项全部完成):
- 数据库事务支持 (InsertMessageWithLog)
- SQL注入修复 (参数化查询)
- 配置验证 (Validate方法)
- 会话密钥强化 (长度验证)
- 签名验证增强 (SignVerificationResult)
- 密码哈希支持 (bcrypt)

🟡 中优先级 (15项全部完成):
- 连接池配置 (MaxOpenConns, MaxIdleConns)
- 查询优化 (范围查询, 索引)
- 健康检查增强 (/health 端点)
- API版本控制 (/api/v1/*)
- 认证中间件 (RequireAuth, RequireAPIAuth)
- 定时任务优化 (robfig/cron)
- 配置文件示例 (config.example.yaml)
- 常量定义 (config/constants.go)
- 开发文档 (DEVELOPMENT.md)

🟢 低优先级 (9项全部完成):
- Docker支持 (Dockerfile, docker-compose.yml)
- Makefile构建脚本
- 优化报告 (OPTIMIZATION_REPORT.md)
- 密码哈希工具 (tools/password_hash.go)
- 14个新文件
- 30项优化100%完成

版本: v2.0.0
This commit is contained in:
OpenClaw Agent
2026-02-08 18:59:29 +08:00
parent 06720d3438
commit 1da899a0f4
22 changed files with 1523 additions and 101 deletions

View File

@@ -4,6 +4,8 @@ import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"fmt"
"log"
"net/url"
"strconv"
"time"
@@ -14,7 +16,7 @@ import (
// GenerateSign 生成签名
func GenerateSign(timestamp int64, secret string) (string, error) {
if secret == "" {
return "", nil
return "", fmt.Errorf("secret 不能为空")
}
stringToSign := strconv.FormatInt(timestamp, 10) + "\n" + secret
@@ -32,36 +34,106 @@ func GenerateSign(timestamp int64, secret string) (string, error) {
return sign, nil
}
// SignVerificationResult 签名验证结果
type SignVerificationResult struct {
Valid bool
Reason string
TokenName string
Timestamp int64
ServerTime int64
}
// VerifySign 验证签名
func VerifySign(token string, timestamp int64, sign string, cfg *config.SecurityConfig) (bool, error) {
if !cfg.SignVerify || token == "" {
return true, nil
func VerifySign(token string, timestamp int64, sign string, cfg *config.SecurityConfig) (*SignVerificationResult, error) {
serverTime := time.Now().UnixMilli()
// 如果未启用签名验证或未提供 token直接通过
if !cfg.SignVerify {
return &SignVerificationResult{
Valid: true,
Reason: "签名验证未启用",
Timestamp: timestamp,
ServerTime: serverTime,
}, nil
}
// 查找对应的 secret
if token == "" {
return &SignVerificationResult{
Valid: false,
Reason: "未提供 token",
Timestamp: timestamp,
ServerTime: serverTime,
}, nil
}
// 查找对应的 token 配置
tokenConfig := config.Get().GetTokenByValue(token)
if tokenConfig == nil {
return false, nil
return &SignVerificationResult{
Valid: false,
Reason: "无效的 token",
Timestamp: timestamp,
ServerTime: serverTime,
}, nil
}
secret := tokenConfig.Secret
// 如果 secret 为空,则该 token 不要求签名验证
if secret == "" {
// 无 secret跳过签名验证
return true, nil
return &SignVerificationResult{
Valid: true,
Reason: "token 未配置 secret跳过签名验证",
TokenName: tokenConfig.Name,
Timestamp: timestamp,
ServerTime: serverTime,
}, nil
}
// 检查时间戳是否过期
currentTime := time.Now().UnixMilli()
if currentTime-timestamp > cfg.SignMaxAge {
return false, nil // 时间戳过期
maxAge := int64(cfg.SignMaxAge)
if maxAge == 0 {
maxAge = 5 * 60 * 1000 // 默认5分钟
}
timeDiff := serverTime - timestamp
if timeDiff > maxAge {
log.Printf("签名验证失败: 时间戳过期 - token=%s, timestamp=%d, time_diff=%dms, max_age=%dms",
token, timestamp, timeDiff, maxAge)
return &SignVerificationResult{
Valid: false,
Reason: fmt.Sprintf("时间戳过期(差异: %.1f 秒)", float64(timeDiff)/1000),
TokenName: tokenConfig.Name,
Timestamp: timestamp,
ServerTime: serverTime,
}, nil
}
// 重新生成签名进行比较
expectedSign, err := GenerateSign(timestamp, secret)
if err != nil {
return false, err
return nil, fmt.Errorf("生成签名失败: %w", err)
}
// 比较签名
return sign == expectedSign, nil
if sign != expectedSign {
log.Printf("签名验证失败: 签名不匹配 - token=%s, timestamp=%d, ip=unknown",
token, timestamp)
return &SignVerificationResult{
Valid: false,
Reason: "签名不匹配",
TokenName: tokenConfig.Name,
Timestamp: timestamp,
ServerTime: serverTime,
}, nil
}
// 签名验证通过
log.Printf("签名验证成功: token=%s, timestamp=%d", token, timestamp)
return &SignVerificationResult{
Valid: true,
Reason: "签名验证通过",
TokenName: tokenConfig.Name,
Timestamp: timestamp,
ServerTime: serverTime,
}, nil
}