-
Notifications
You must be signed in to change notification settings - Fork 19
AI Chat Service: 认证/会话持久化/Redis 缓存/列表与清理接口 + 文档同步 #19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
smf-h
wants to merge
1
commit into
hduhelp:main
Choose a base branch
from
smf-h:pr/smf-h-ai-chat
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
# AI Chat Service | ||
|
||
一个包含用户认证、模型权限控制、会话持久化、历史缓存与 Swagger 文档的简化 AI 多轮对话示例服务。 | ||
|
||
## 功能特性 | ||
- 用户注册 / 登录(JWT,环境变量可覆盖密钥) | ||
- 模型访问权限控制(用户等级 / 角色 + 模型最小等级) | ||
- 会话与消息:MySQL 持久化 + 内存缓存 + 最近历史 Redis 缓存 | ||
- 统一错误码与结构化响应(支持多类错误 swagger 展示) | ||
- Swagger 文档(动态生成) | ||
- 环境变量安全覆写配置,真实 `config.yaml` 不提交 | ||
- Redis 可选:失败自动降级不影响主流程 | ||
|
||
## 快速启动 (Windows PowerShell) | ||
```powershell | ||
# 可选:克隆后进入目录 | ||
# git clone <your-fork-url> && cd awesomeProject | ||
|
||
# 1. 准备示例配置(真实敏感值用环境变量覆盖) | ||
Copy-Item config\config.example.yaml config\config.yaml | ||
|
||
# 2. 设置必要环境变量(示例,可按需调整) | ||
$env:MYSQL_PASSWORD = "your_mysql_password" | ||
$env:AUTH_JWT_SECRET = "your_jwt_secret" | ||
# 如果需要真实模型调用 | ||
# $env:ARK_API_KEY = "your_model_api_key" | ||
|
||
# 3. 启动服务 | ||
go run main.go | ||
|
||
# 4. 打开 Swagger | ||
# http://localhost:8080/swagger/index.html | ||
``` | ||
|
||
## 错误码对照(节选) | ||
| code | 含义 | | ||
|------|------| | ||
| 0 | 成功 | | ||
| 40001 | 参数错误 | | ||
| 40002 | 模型不存在或未配置 | | ||
| 40101 | 未认证 | | ||
| 40301 | 模型权限不足 | | ||
| 40302 | 会话归属错误 | | ||
| 50000 | 内部错误 | | ||
| 50001 | 模型返回为空 | | ||
|
||
完整说明参见:`docs/api.md` | ||
|
||
## 目录说明 | ||
``` | ||
internal/ 内部逻辑模块 | ||
auth/ JWT、密码哈希、中间件 | ||
config/ 配置加载与环境变量覆写 | ||
db/ 数据库初始化 | ||
memory/ 内存会话管理 | ||
models/ GORM 实体 | ||
redisstore/ Redis 可选缓存封装 | ||
config/ 配置文件目录(示例 + 本地实际) | ||
docs/ 架构/接口/安全/代码说明文档 | ||
main.go 程序入口与路由 | ||
``` | ||
|
||
## 常见环境变量 | ||
``` | ||
MYSQL_HOST / MYSQL_PORT / MYSQL_USER / MYSQL_PASSWORD / MYSQL_DB / MYSQL_CHARSET | ||
AUTH_JWT_SECRET / AUTH_ACCESS_TTL | ||
CHAT_DEFAULT_MODEL / CHAT_MAX_HISTORY / CHAT_MEMORY_LIMIT_MSGS | ||
REDIS_HOST / REDIS_PORT / REDIS_PASSWORD / REDIS_DB | ||
``` | ||
详细列表:`docs/SECURITY_CONFIG.md` | ||
|
||
## Redis 最近历史缓存 | ||
- Key: `chat:conv:recent:<conversation_id>` | ||
- 写入:发送消息成功后 | ||
- 读取:历史接口优先命中;失败走 DB 回源 | ||
- 降级:Redis 初始化失败时自动忽略缓存 | ||
|
||
## 后续可扩展 | ||
- SSE 流式输出 | ||
- 速率限制 (Redis Incr) | ||
- 会话列表接口 | ||
- 模型 Provider 抽象层 | ||
|
||
## PR / 评审建议 | ||
- 不要提交 `config/config.yaml` | ||
- 通过 README 步骤可本地快速运行 | ||
- 安全策略见 `docs/SECURITY_CONFIG.md` | ||
|
||
## License | ||
按上游仓库策略或后续补充。 | ||
|
||
--- | ||
**END** |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# 示例配置文件。提交 PR 时请使用本文件,真实敏感信息放在本地 config.yaml(已被 .gitignore 忽略)。 | ||
server: | ||
port: 8080 | ||
mode: release | ||
mysql: | ||
host: 127.0.0.1 | ||
port: 3306 | ||
user: root | ||
password: CHANGE_ME | ||
database: ai_chat | ||
charset: utf8mb4 | ||
chat: | ||
default_model: doubao-seed-1-6-250615 | ||
max_history: 12 | ||
memory_limit_msgs: 200 | ||
request_timeout: 15s | ||
auth: | ||
jwt_secret: CHANGE_ME_JWT_SECRET | ||
access_ttl: 24h | ||
models: | ||
- id: doubao-seed-1-6-250615 | ||
min_level: 1 | ||
- id: deepseek-v3-1-terminus | ||
min_level: 3 | ||
- id: kimi-k2-250905 | ||
min_level: 5 | ||
redis: | ||
host: 127.0.0.1 | ||
port: 6379 | ||
password: "" # 本地无密码 | ||
db: 0 | ||
pool_size: 20 | ||
dial_timeout: 2s | ||
read_timeout: 1s | ||
write_timeout: 1s | ||
|
||
# 使用环境变量覆盖敏感值 (示例): | ||
# setx MYSQL_PASSWORD "real_password" | ||
# setx AUTH_JWT_SECRET "real_jwt_secret" | ||
# setx REDIS_PASSWORD "redis_pwd" | ||
# 或 PowerShell 当前会话: | ||
# $env:MYSQL_PASSWORD="real_password" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
server: | ||
port: 8080 | ||
mode: debug | ||
mysql: | ||
host: 127.0.0.1 | ||
port: 3306 | ||
user: root | ||
password: 2823128231 | ||
database: ai_chat | ||
charset: utf8mb4 | ||
chat: | ||
default_model: doubao-seed-1-6-250615 | ||
max_history: 12 | ||
memory_limit_msgs: 200 | ||
request_timeout: 15s | ||
auth: | ||
jwt_secret: change_me_dev_secret | ||
access_ttl: 24h | ||
models: | ||
- id: doubao-seed-1-6-250615 | ||
min_level: 1 | ||
- id: deepseek-v3-1-terminus | ||
min_level: 3 | ||
- id: kimi-k2-250905 | ||
min_level: 5 | ||
|
||
redis: | ||
host: 127.0.0.1 | ||
port: 6379 | ||
# password: 2823128231 | ||
db: 0 | ||
pool_size: 20 | ||
dial_timeout: 2s | ||
read_timeout: 1s | ||
write_timeout: 1s | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
# 配置与密钥安全指南 | ||
|
||
本指南说明如何在提交代码(PR)时避免泄露敏感信息,并保证不同环境(本地/测试/生产)配置隔离。 | ||
|
||
## 1. 不要提交的内容 | ||
- 真实 `config/config.yaml` (已加入 .gitignore) | ||
- 数据库密码、JWT 密钥、第三方 API Key (如 ARK_API_KEY) | ||
- 生产 Redis / MySQL 地址 | ||
- 私有证书、密钥对、令牌文件 | ||
|
||
## 2. 提交什么 | ||
| 文件 | 作用 | 是否包含敏感信息 | | ||
|------|------|------------------| | ||
| `config/config.example.yaml` | 示例/模板 | 否(占位符) | | ||
| `internal/config/config.go` | 解析 + 环境变量覆盖 | 否 | | ||
| `.gitignore` | 忽略真实配置 | 否 | | ||
|
||
## 3. 本地真实配置放哪里 | ||
- 开发: `config/config.yaml` (不会被 git 追踪) | ||
- 生产: 推荐使用环境变量 + 仅最小必要的 fallback config 文件 | ||
|
||
## 4. 环境变量覆盖支持 (已实现) | ||
支持的变量 (非空即覆盖): | ||
``` | ||
SERVER_PORT, SERVER_MODE | ||
MYSQL_HOST, MYSQL_PORT, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DB, MYSQL_CHARSET | ||
AUTH_JWT_SECRET, AUTH_ACCESS_TTL | ||
CHAT_DEFAULT_MODEL, CHAT_MAX_HISTORY, CHAT_MEMORY_LIMIT_MSGS, CHAT_REQUEST_TIMEOUT | ||
REDIS_HOST, REDIS_PORT, REDIS_PASSWORD, REDIS_DB, REDIS_POOL_SIZE, | ||
REDIS_DIAL_TIMEOUT, REDIS_READ_TIMEOUT, REDIS_WRITE_TIMEOUT | ||
``` | ||
示例 (PowerShell 临时会话): | ||
```powershell | ||
$env:MYSQL_PASSWORD = "SuperSecret!" | ||
$env:AUTH_JWT_SECRET = "ProdJwtSecret_ChangeMe" | ||
$env:REDIS_PASSWORD = "RedisPwd123" | ||
``` | ||
|
||
## 5. PR 前自检清单 | ||
| 检查项 | 通过条件 | | ||
|--------|----------| | ||
| config.yaml 是否未被提交 | `git status` 无该文件 | | ||
| 未把真实密码硬编码进代码 | 搜索 `password:` / `jwt_secret:` 无真实值 | | ||
| 关键密钥均可用 env 注入 | 启动服务时通过日志/调试确认被覆盖 | | ||
|
||
## 6. CI/CD 建议 | ||
- 使用平台 Secret 管理 (GitHub Actions Secrets / GitLab CI Variables) | ||
- 部署启动脚本导出变量后再 `go run / build`: | ||
```bash | ||
export MYSQL_PASSWORD=$SECRET_MYSQL_PASSWORD | ||
export AUTH_JWT_SECRET=$SECRET_JWT | ||
./app | ||
``` | ||
- 避免将密钥写入镜像层:用运行时注入 (Kubernetes Secret / Docker --env-file) | ||
|
||
## 7. 生产加固建议 | ||
| 领域 | 建议 | | ||
|------|------| | ||
| JWT | 定期轮换密钥,考虑多个版本(旧+新)并行过渡 | | ||
| 数据库 | 最小权限账号,禁止 *.* 全权限;开启 TLS (如需) | | ||
| Redis | 绑定内网地址,启用 ACL 或至少强密码,禁止公网暴露 | | ||
| 日志 | 不打印 token / 密码 / 完整 SQL (参数可脱敏) | | ||
| 代码 | 通过 secret 扫描工具 (trufflehog / gitleaks) 预防泄露 | | ||
|
||
## 8. 临时调试不泄露技巧 | ||
- 打印配置时跳过敏感字段 (`****`)。 | ||
- 将敏感值长度或 hash 输出用于核对是否加载到了正确的 Secret。 | ||
|
||
## 9. 应急处理 | ||
| 场景 | 动作 | | ||
|------|------| | ||
| 不小心提交密钥 | 立即在平台侧作废该密钥;强制推送清理历史(必要时);生成新 Key | | ||
| 密钥疑似泄露 | 强制失效 + 全局通知 + 轮换;审计访问日志 | | ||
| 配置被恶意篡改 | 使用只读挂载或配置签名校验 | | ||
|
||
## 10. 后续可增强 | ||
- 引入 `.env` + dotenv 解析(本项目目前依赖系统 env) | ||
- 加入启动时敏感配置缺失校验并统一错误提示 | ||
- 敏感值自动检测 pre-commit 钩子 | ||
- 支持 Vault / Secrets Manager 远程加载 | ||
|
||
--- | ||
**END** |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
严重安全问题:敏感配置文件不应提交到代码库。
此文件包含真实的敏感信息:
2823128231
根据 PR 目标和 README.md(第 86 行)的明确说明:"不要提交
config/config.yaml
"。必须立即采取的措施:
config/config.yaml
文件.gitignore
(如果尚未添加)config.example.yaml
作为模板,用户应在本地复制并填入真实值git filter-branch
或 BFG Repo-Cleaner 清理历史参考
config/config.example.yaml
的正确做法:使用CHANGE_ME
等占位符,并通过环境变量覆盖敏感值。🤖 Prompt for AI Agents