Files
openteam/server/internal/pkg/apikey/apikey.go
T
SakurasanandClaude ec4de8d913 M0-M4: 推倒重来基线(基建+用户/密钥/核心代理+前端+管理后台+三协议互转)
- 后端 Go+Gin+GORM: 配置(OT_ env)/SQLite/Postgres 双驱动、用户体系(argon2id+JWT access/refresh)、
  API Key(sk- 48位, 仅存 SHA-256 哈希)
- 代理网关: /v1/chat/completions、/v1/responses、/v1/messages、/v1/models;错误按客户端协议返回
- 三协议互转(convert 包): Chat↔Messages↔Responses 请求/响应 + 流式 SSE 逐事件转换(直通优先)
- 用量计费: 异步批量记账、余额扣减、balance_logs、usage_daily 日聚合
- 管理 API: 用户/渠道 CRUD+测试+模型导入/模型定价+绑定/统计/系统配置
- 前端 Vue3+TS+Tailwind(taste-skill 设计 tokens): Landing/登录注册/控制台/管理后台,
  自建组件+Phosphor 图标+自建 SVG 趋势图, 已过 web-design-guidelines 复查
- mock 上游: OpenAI+Anthropic 双协议模拟(含流式)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-15 15:34:06 +08:00

49 lines
1.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Package apikey 生成与管理 API Key:sk- + 48 位 base62 随机串。
// 库中仅存 SHA-256 哈希与展示前缀(PLANNING §4.3.3)。
package apikey
import (
"crypto/rand"
"crypto/sha256"
"encoding/hex"
"strings"
)
const (
alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
keyLen = 48
prefix = "sk-"
)
// Generate 生成明文 key(仅创建时展示一次)与哈希、前缀。
func Generate() (plain, hash, keyPrefix string, err error) {
buf := make([]byte, keyLen)
if _, err = rand.Read(buf); err != nil {
return "", "", "", err
}
for i := range buf {
buf[i] = alphabet[int(buf[i])%len(alphabet)]
}
plain = prefix + string(buf)
return plain, Hash(plain), Prefix(plain), nil
}
// Hash 返回 key 的 SHA-256 十六进制。
func Hash(key string) string {
sum := sha256.Sum256([]byte(key))
return hex.EncodeToString(sum[:])
}
// Prefix 展示前缀:sk-aB3cD5…(前 12 字符)
func Prefix(key string) string {
if len(key) <= 12 {
return key
}
return key[:12]
}
// Valid 校验明文格式。
func Valid(key string) bool {
return strings.HasPrefix(key, prefix) && len(key) == len(prefix)+keyLen
}