更新readme

This commit is contained in:
2025-12-26 21:32:32 +08:00
parent 85a9463913
commit 9e83ae16af

646
README.md
View File

@@ -1,564 +1,160 @@
# CarrotSkin Backend # CarrotSkin Backend
一个功能完善的Minecraft皮肤站后端系统,采用单体架构设计基于Go语言和Gin框架开发 一个功能完善的 Minecraft 皮肤站后端,基于 Go + Gin 构建,覆盖用户认证、材质管理、角色档案、审计日志等核心能力,并提供完整的 Swagger 文档与容器友好的环境变量配置
## ✨ 核心功能 ## ✨ 功能亮点
- **用户认证系统** - 注册、登录、JWT认证、积分系统 - **账号体系**:注册 / 登录 / JWT 鉴权 / Yggdrasil 密码同步 / 用户积分
- **邮箱验证系统** - 注册验证、找回密码、更换邮箱基于Redis的验证码 - **邮箱验证码**:验证码发送频率控制、邮箱绑定与变更
- **材质管理系统** - 皮肤/披风上传、搜索、收藏、下载统计 - **材质中心**皮肤/披风上传、搜索、收藏、下载统计、Hash 去重
- **角色档案系统** - Minecraft角色创建、管理、RSA密钥生成 - **角色档案**Minecraft Profile 管理、RSA 密钥生成、活跃档案切换
- **文件存储** - MinIO/RustFS对象存储集成、预签名URL上传 - **存储与上传**RustFS/MinIO 预签名 URL,减轻服务器带宽压力
- **缓存系统** - Redis缓存、验证码存储、频率限制 - **任务与日志**:登录日志、操作审计、材质下载记录、定时任务
- **权限管理** - Casbin RBAC权限控制 - **权限体系**Casbin RBAC,支持细粒度路线授
- **数据审计** - 登录日志、操作审计、下载记录 - **配置管理**100% 依赖环境变量,`SERVER_SWAGGER_ENABLED` 控制 Swagger
- **可观测性**Zap 结构化日志、统一 API 响应模型
## 项目结构 ## 🛠 技术栈
| 类型 | 选型 |
| --- | --- |
| 语言 / 运行时 | Go 1.24+ |
| Web 框架 | Gin |
| ORM | GORM (PostgreSQL 驱动) |
| 数据库 | PostgreSQL 15+ |
| 缓存 / 消息 | Redis 6+ |
| 对象存储 | RustFS / MinIOS3 兼容) |
| 权限控制 | Casbin |
| 配置 | Viper + `.env` |
| API 文档 | swaggo / Swagger UI |
| 日志 | Uber Zap |
## 📁 目录结构
``` ```
backend/ backend/
├── cmd/ # 应用程序入口 ├── cmd/server/ # 应用入口main.go
│ └── server/ # 主服务器入口 ├── internal/
└── main.go # 服务初始化、路由注册 ├── handler/ # HTTP Handler 与 Swagger 注解
├── internal/ # 私有应用代码 │ ├── service/ # 业务逻辑
│ ├── handler/ # HTTP处理器函数式 │ ├── repository/ # 数据访问
│ ├── routes.go # 路由注册 │ ├── model/ # GORM 数据模型
│ ├── auth_handler.go │ ├── types/ # 请求/响应 DTO
│ ├── user_handler.go │ ├── middleware/ # Gin 中间件
│ └── ... └── task/ # 定时任务与后台作业
│ ├── service/ # 业务逻辑服务(函数式 ├── pkg/ # 可复用组件config、database、auth、logger、redis、storage 等
├── common.go # 公共声明jsoniter等 ├── docs/ # swagger 生成产物docs.go / swagger.json / swagger.yaml
├── user_service.go ├── start.sh # 启动脚本(自动 swag init
└── ... ├── docker-compose.yml # 本地容器编排
│ ├── repository/ # 数据访问层(函数式) ├── .env.example # 环境变量示例
├── user_repository.go └── go.mod # Go Module 定义
│ │ └── ...
│ ├── model/ # 数据模型GORM
│ ├── middleware/ # 中间件
│ └── types/ # 类型定义
├── pkg/ # 公共库代码
│ ├── auth/ # 认证授权
│ │ └── manager.go # JWT服务管理器
│ ├── config/ # 配置管理
│ │ └── manager.go # 配置管理器
│ ├── database/ # 数据库连接
│ │ ├── manager.go # 数据库管理器AutoMigrate
│ │ └── postgres.go # PostgreSQL连接
│ ├── email/ # 邮件服务
│ │ └── manager.go # 邮件服务管理器
│ ├── logger/ # 日志系统
│ │ └── manager.go # 日志管理器
│ ├── redis/ # Redis客户端
│ │ └── manager.go # Redis管理器
│ ├── storage/ # 文件存储(RustFS/MinIO)
│ │ └── manager.go # 存储管理器
│ ├── utils/ # 工具函数
│ └── validator/ # 数据验证
├── docs/ # API定义和文档Swagger
├── configs/ # 配置文件
│ └── casbin/ # Casbin权限配置
├── go.mod # Go模块依赖
├── go.sum # Go模块校验
├── start.sh # Linux/Mac启动脚本
├── .env # 环境变量配置
└── README.md # 项目说明
``` ```
## 技术栈 ## ✅ 前置要求
- **语言**: Go 1.23+ - Go 1.24+
- **框架**: Gin Web Framework - PostgreSQL 15+
- **数据库**: PostgreSQL 15+ (GORM ORM) - Redis 6+
- **缓存**: Redis 6.0+ - RustFS / MinIO或其他兼容 S3 的对象存储,用于皮肤与头像)
- **存储**: RustFS/MinIO (S3兼容对象存储)
- **权限**: Casbin RBAC
- **日志**: Zap (结构化日志)
- **配置**: 环境变量 (.env) + Viper
- **JSON**: jsoniter (高性能JSON序列化)
- **文档**: Swagger/OpenAPI 3.0
## 快速开始 ## 🚀 快速开始
### 环境要求 1. **克隆仓库**
```bash
- Go 1.21或更高版本 git clone <repo>
- PostgreSQL 15或更高版本 cd backend
- Redis 6.0或更高版本 ```
- RustFS 或其他 S3 兼容对象存储服务
### 安装和运行
1. **克隆项目**
```bash
git clone <repository-url>
cd CarrotSkin/backend
```
2. **安装依赖** 2. **安装依赖**
```bash ```bash
go mod download go mod download
``` ```
3. **配置环境** 3. **配置环境变量**
```bash ```bash
# 复制环境变量文件 cp .env.example .env
cp .env.example .env # 根据实际环境填写数据库、Redis、对象存储、邮件等信息
# 编辑 .env 文件配置数据库、RustFS等服务连接信息 ```
```
**注意**:项目完全依赖 `.env` 文件进行配置,不再使用 YAML 配置文件,便于 Docker 容器化部署。
4. **初始化数据库** 4. **初始化数据库**
```bash ```bash
# 创建数据库 createdb carrotskin
createdb carrotskin # 或 psql -c "CREATE DATABASE carrotskin;"
# 或者使用PostgreSQL客户端 ```
psql -h localhost -U postgres -c "CREATE DATABASE carrotskin;" > 应用启动时会执行 `AutoMigrate`,自动创建 / 更新表结构。
```
> 💡 **提示**: 项目使用 GORM 的 `AutoMigrate` 功能自动创建和更新数据库表结构无需手动执行SQL脚本。首次启动时会自动创建所有表。 5. **启动服务**
- **推荐**`./start.sh`(自动 `swag init`,随后 `go run cmd/server/main.go`
- **手动启动**
```bash
swag init -g cmd/server/main.go -o docs
go run cmd/server/main.go
```
5. **运行服务** 6. **访问接口**
- API Root: `http://localhost:8080`
- Swagger: `http://localhost:8080/swagger/index.html`(需 `SERVER_SWAGGER_ENABLED=true`
方式一:使用启动脚本(推荐) ## ⚙️ 关键环境变量
```bash
# Linux/Mac
chmod +x start.sh
./start.sh
# Windows | 变量 | 说明 | 示例 |
start.bat | --- | --- | --- |
``` | `SERVER_PORT` | 服务监听端口 | `8080` |
| `SERVER_MODE` | Gin 模式debug/release | `debug` |
| `SERVER_SWAGGER_ENABLED` | 是否暴露 Swagger UI | `true` |
| `DATABASE_HOST` / `DATABASE_PORT` | PostgreSQL 地址 | `localhost` / `5432` |
| `DATABASE_USERNAME` / `DATABASE_PASSWORD` | 数据库凭据 | `postgres` |
| `DATABASE_NAME` | 数据库名称 | `carrotskin` |
| `REDIS_HOST` / `REDIS_PORT` | Redis 地址 | `localhost` / `6379` |
| `REDIS_PASSWORD` | Redis 密码(无可为空) | `` |
| `RUSTFS_ENDPOINT` | RustFS/MinIO 访问地址 | `127.0.0.1:9000` |
| `RUSTFS_ACCESS_KEY` / `RUSTFS_SECRET_KEY` | 对象存储凭据 | `minioadmin` |
| `RUSTFS_BUCKET_TEXTURES` / `RUSTFS_BUCKET_AVATARS` | 存储桶名称 | `carrotskin-textures` |
| `JWT_SECRET` | JWT 签名密钥 | `change-me` |
| `EMAIL_ENABLED` | 是否开启邮件服务 | `true` |
| `EMAIL_SMTP_HOST` / `EMAIL_SMTP_PORT` | SMTP 配置 | `smtp.example.com` / `587` |
方式二:直接运行 更多变量请参考 `.env.example` 与 `.env.docker.example`。
```bash
# 设置环境变量(或使用.env文件
export DATABASE_HOST=localhost
export DATABASE_PORT=5432
# ... 其他环境变量
# 运行服务 ## 🧪 常用命令
go run cmd/server/main.go
```
> 💡 **提示**:
> - 启动脚本会自动加载 `.env` 文件中的环境变量
> - 首次启动时会自动执行数据库迁移AutoMigrate
> - 如果对象存储未配置,服务仍可启动(相关功能不可用)
服务启动后:
- **服务地址**: http://localhost:8080
- **Swagger文档**: http://localhost:8080/swagger/index.html
- **健康检查**: http://localhost:8080/health
## API接口
### 认证相关
- `POST /api/v1/auth/register` - 用户注册(需邮箱验证码)
- `POST /api/v1/auth/login` - 用户登录(支持用户名/邮箱)
- `POST /api/v1/auth/send-code` - 发送验证码(注册/重置密码/更换邮箱)
- `POST /api/v1/auth/reset-password` - 重置密码(需验证码)
### 用户相关(需认证)
- `GET /api/v1/user/profile` - 获取用户信息
- `PUT /api/v1/user/profile` - 更新用户信息(头像、密码)
- `POST /api/v1/user/avatar/upload-url` - 生成头像上传URL
- `PUT /api/v1/user/avatar` - 更新头像
- `POST /api/v1/user/change-email` - 更换邮箱(需验证码)
### 材质管理
公开接口:
- `GET /api/v1/texture` - 搜索材质
- `GET /api/v1/texture/:id` - 获取材质详情
认证接口:
- `POST /api/v1/texture/upload-url` - 生成材质上传URL
- `POST /api/v1/texture` - 创建材质记录
- `PUT /api/v1/texture/:id` - 更新材质
- `DELETE /api/v1/texture/:id` - 删除材质
- `POST /api/v1/texture/:id/favorite` - 切换收藏状态
- `GET /api/v1/texture/my` - 我的材质列表
- `GET /api/v1/texture/favorites` - 我的收藏列表
### 角色档案
公开接口:
- `GET /api/v1/profile/:uuid` - 获取档案详情
认证接口:
- `POST /api/v1/profile` - 创建角色档案UUID由后端生成
- `GET /api/v1/profile` - 我的档案列表
- `PUT /api/v1/profile/:uuid` - 更新档案
- `DELETE /api/v1/profile/:uuid` - 删除档案
- `POST /api/v1/profile/:uuid/activate` - 设置活跃档案
### 系统配置
- `GET /api/v1/system/config` - 获取系统配置
## 配置管理
### 环境变量配置
项目**完全依赖环境变量**进行配置,不使用 YAML 配置文件,便于容器化部署:
1. **配置来源**: 环境变量 或 `.env` 文件
2. **环境变量格式**: 使用下划线分隔,全大写,如 `DATABASE_HOST`
3. **容器部署**: 直接在容器运行时设置环境变量即可
**主要环境变量**:
```bash
# 数据库配置
DATABASE_HOST=localhost
DATABASE_PORT=5432
DATABASE_USERNAME=postgres
DATABASE_PASSWORD=your_password
DATABASE_NAME=carrotskin
# Redis配置
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=your_redis_password
REDIS_DATABASE=0
REDIS_POOL_SIZE=10
# RustFS对象存储配置 (S3兼容)
RUSTFS_ENDPOINT=127.0.0.1:9000
RUSTFS_ACCESS_KEY=your_access_key
RUSTFS_SECRET_KEY=your_secret_key
RUSTFS_USE_SSL=false
RUSTFS_BUCKET_TEXTURES=carrot-skin-textures
RUSTFS_BUCKET_AVATARS=carrot-skin-avatars
# JWT配置
JWT_SECRET=your-jwt-secret-key
JWT_EXPIRE_HOURS=168
# 邮件配置
EMAIL_ENABLED=true
EMAIL_SMTP_HOST=smtp.example.com
EMAIL_SMTP_PORT=587
EMAIL_USERNAME=noreply@example.com
EMAIL_PASSWORD=your_email_password
EMAIL_FROM_NAME=CarrotSkin
```
**动态配置(存储在数据库中)**:
- 积分系统配置(注册奖励、签到积分等)
- 用户限制配置(最大材质数、最大角色数等)
- 网站设置(站点名称、公告、维护模式等)
完整的环境变量列表请参考 `.env.example` 文件。
### 数据库自动迁移
项目使用 GORM 的 `AutoMigrate` 功能自动管理数据库表结构:
- **首次启动**: 自动创建所有表结构
- **模型更新**: 自动添加新字段、索引等
- **类型转换**: 自动处理字段类型变更如枚举类型转为varchar
- **外键管理**: 自动管理外键关系
**注意事项**:
- 生产环境建议先备份数据库再执行迁移
- 某些复杂变更(如删除字段)可能需要手动处理
- 枚举类型在PostgreSQL中存储为varchar避免类型兼容问题
## 架构设计
### 面向过程的函数式架构
项目采用**面向过程的函数式架构**,摒弃不必要的面向对象抽象,使用独立函数和单例管理器模式,代码更简洁、可维护性更强:
```
┌─────────────────────────────────────┐
│ Handler 层 (函数) │ ← 路由处理、参数验证、响应格式化
├─────────────────────────────────────┤
│ Service 层 (函数) │ ← 业务逻辑、权限检查、数据验证
├─────────────────────────────────────┤
│ Repository 层 (函数) │ ← 数据库操作、关联查询
├─────────────────────────────────────┤
│ Manager 层 (单例模式) │ ← 核心依赖管理(线程安全)
│ - database.MustGetDB() │
│ - logger.MustGetLogger() │
│ - auth.MustGetJWTService() │
│ - redis.MustGetClient() │
│ - email.MustGetService() │
│ - storage.MustGetClient() │
│ - config.MustGetConfig() │
├──────────────┬──────────────────────┤
│ PostgreSQL │ Redis │ RustFS │ ← 数据存储层
└──────────────┴──────────────────────┘
```
### 架构特点
1. **函数式设计**: 所有业务逻辑以独立函数形式实现,无结构体方法,降低耦合度
2. **管理器模式**: 使用 `sync.Once` 实现线程安全的单例管理器,统一管理核心依赖
3. **按需获取**: 通过管理器函数按需获取依赖,避免链式传递,代码更清晰
4. **自动迁移**: 使用 GORM AutoMigrate 自动管理数据库表结构
5. **高性能**: 使用 jsoniter 替代标准库 json提升序列化性能
### 核心模块
1. **认证模块** (`internal/handler/auth_handler.go`)
- JWT令牌生成和验证通过 `auth.MustGetJWTService()` 获取)
- bcrypt密码加密
- 邮箱验证码注册
- 密码重置功能
- 登录日志记录(支持用户名/邮箱登录)
2. **用户模块** (`internal/handler/user_handler.go`)
- 用户信息管理
- 头像上传预签名URL通过 `storage.MustGetClient()` 获取)
- 密码修改(需原密码验证)
- 邮箱更换(需验证码)
- 积分系统
3. **邮箱验证模块** (`internal/service/verification_service.go`)
- 验证码生成6位数字
- 验证码存储Redis10分钟有效期通过 `redis.MustGetClient()` 获取)
- 发送频率限制1分钟
- 邮件发送HTML格式通过 `email.MustGetService()` 获取)
4. **材质模块** (`internal/handler/texture_handler.go`)
- 材质上传预签名URL
- 材质搜索和收藏
- Hash去重
- 下载统计
5. **档案模块** (`internal/handler/profile_handler.go`)
- Minecraft角色管理
- RSA密钥生成RSA-2048
- 活跃状态管理
- 档案数量限制
6. **管理器模块** (`pkg/*/manager.go`)
- 数据库管理器:`database.MustGetDB()` - 线程安全的数据库连接
- 日志管理器:`logger.MustGetLogger()` - 结构化日志实例
- JWT管理器`auth.MustGetJWTService()` - JWT服务实例
- Redis管理器`redis.MustGetClient()` - Redis客户端
- 邮件管理器:`email.MustGetService()` - 邮件服务
- 存储管理器:`storage.MustGetClient()` - 对象存储客户端
- 配置管理器:`config.MustGetConfig()` - 应用配置
### 技术特性
- **架构优势**:
- 面向过程的函数式设计,代码简洁清晰
- 单例管理器模式,线程安全的依赖管理
- 按需获取依赖,避免链式传递
- 自动数据库迁移AutoMigrate
- **安全性**:
- bcrypt密码加密、JWT令牌认证
- 邮箱验证码(注册/重置密码/更换邮箱)
- Casbin RBAC权限控制
- 频率限制(防暴力破解)
- **性能**:
- jsoniter 高性能JSON序列化替代标准库
- PostgreSQL索引优化
- Redis缓存验证码、会话等
- 预签名URL减轻服务器压力
- 连接池管理
- **可靠性**:
- 事务保证数据一致性
- 完整的错误处理和日志记录
- 优雅关闭和资源清理
- 对象存储连接失败时服务仍可启动
- **可扩展**:
- 清晰的函数式架构
- 管理器模式统一管理依赖
- 环境变量配置(便于容器化)
- **审计**:
- 登录日志(成功/失败)
- 操作审计
- 下载记录
## 开发指南
### 代码结构
- `cmd/server/` - 应用入口,初始化服务
- `internal/handler/` - HTTP请求处理
- `internal/service/` - 业务逻辑实现
- `internal/repository/` - 数据库操作
- `internal/model/` - 数据模型定义
- `internal/types/` - 请求/响应类型定义
- `internal/middleware/` - 中间件JWT、CORS、日志等
- `pkg/` - 可复用的公共库
### 开发规范
1. **代码风格**: 遵循Go官方代码规范使用 `gofmt` 格式化
2. **架构模式**: 使用函数式设计,避免不必要的结构体和方法
3. **依赖管理**: 通过管理器函数获取依赖(如 `database.MustGetDB()`),避免链式传递
4. **错误处理**: 使用统一的错误响应格式 (`model.NewErrorResponse`)
5. **日志记录**: 使用 Zap 结构化日志,通过 `logger.MustGetLogger()` 获取实例
6. **JSON序列化**: 使用 jsoniter 替代标准库 json提升性能
7. **RESTful API**: 遵循 REST 设计原则合理使用HTTP方法
### 添加新功能
1.`internal/model/` 定义数据模型GORM会自动迁移
2.`internal/repository/` 实现数据访问函数(使用 `database.MustGetDB()` 获取数据库)
3.`internal/service/` 实现业务逻辑函数(按需使用管理器获取依赖)
4.`internal/handler/` 实现HTTP处理函数使用管理器获取logger、jwtService等
5.`internal/handler/routes.go` 注册路由
**示例**:
```go
// Repository层
func FindUserByID(id uint) (*model.User, error) {
db := database.MustGetDB()
var user model.User
err := db.First(&user, id).Error
return &user, err
}
// Service层
func GetUserProfile(userID uint) (*model.User, error) {
logger := logger.MustGetLogger()
user, err := repository.FindUserByID(userID)
if err != nil {
logger.Error("获取用户失败", zap.Error(err))
return nil, err
}
return user, nil
}
// Handler层
func GetUserProfile(c *gin.Context) {
logger := logger.MustGetLogger()
jwtService := auth.MustGetJWTService()
// ... 处理逻辑
}
```
## 部署
### 本地开发
```bash ```bash
# 安装依赖 # 运行单元测试
go mod download go test ./...
# 配置环境变量(创建.env文件或直接export # 重新生成 swagger
cp .env.example .env swag init -g cmd/server/main.go -o docs
# 编辑 .env 文件
# 启动服务 # 代码格式化 / 静态检查
# 方式1: 使用启动脚本 gofmt -w .
./start.sh # Linux/Mac golangci-lint run (若已安装)
start.bat # Windows
# 方式2: 直接运行
go run cmd/server/main.go
``` ```
**首次启动**: ## 🧱 架构说明
- 会自动执行数据库迁移AutoMigrate创建所有表结构
- 如果对象存储未配置,会记录警告但服务仍可启动
- 检查日志确认所有服务初始化成功
### 生产部署 - **分层设计**Handler -> Service -> Repository -> Model层次清晰、职责单一。
- **依赖管理器**`pkg/*/manager.go` 使用 `sync.Once` 实现线程安全单例DB / Redis / Logger / Storage / Email / Auth / Config
- **Swagger 注解**:所有 Handler、模型、DTO 均补齐 `@Summary` / `@Description` / `@Success`,可直接生成 OpenAPI 文档。
- **配置优先级**`.env` -> 系统环境变量,所有配置均可通过容器注入。
- **自动任务**`internal/task` 承载后台作业,可按需扩展。
```bash ## 📝 Swagger 说明
# 构建二进制文件
go build -o carrotskin-server cmd/server/main.go
# 运行服务 - `start.sh` 会在启动前执行 `swag init -g cmd/server/main.go -o docs`
./carrotskin-server - 若手动运行,需要保证 `docs/` 下的 `docs.go`、`swagger.json`、`swagger.yaml` 与代码同步
``` - 通过 `SERVER_SWAGGER_ENABLED=false` 可在生产环境关闭 Swagger UI 暴露
### Docker部署 ## 🤝 贡献指南
```bash 1. Fork & Clone
# 构建镜像 2. 创建特性分支:`git checkout -b feature/xxx`
docker build -t carrotskin-backend:latest . 3. 编写代码并补全测试 / Swagger 注释
4. 提交时附上变更说明
# 启动服务 ## 📄 许可证
docker-compose up -d
```
## 故障排查 该项目未附带开源许可证,默认保留所有权利。若需对外使用,请先与作者确认协议。
### 常见问题 ---
1. **数据库连接失败** 如需了解业务细节或 API 调用示例,请参考 `docs/swagger.yaml` 或运行服务后访问 Swagger UI。祝编码愉快🍀
- 检查 `.env` 中的数据库配置(`DATABASE_HOST`, `DATABASE_PORT`, `DATABASE_USERNAME`, `DATABASE_PASSWORD`, `DATABASE_NAME`
- 确认PostgreSQL服务已启动
- 验证数据库用户权限
- 确认数据库已创建:`createdb carrotskin``psql -c "CREATE DATABASE carrotskin;"`
- 检查数据库迁移日志,确认表结构创建成功
2. **Redis连接失败**
- 检查Redis服务是否运行`redis-cli ping`
- 验证 `.env` 中的Redis配置
- 确认Redis密码是否正确
- 检查防火墙规则
3. **RustFS/MinIO连接失败**
- 检查存储服务是否运行
- 验证访问密钥是否正确(`RUSTFS_ACCESS_KEY`, `RUSTFS_SECRET_KEY`
- 确认存储桶是否已创建(`RUSTFS_BUCKET_TEXTURES`, `RUSTFS_BUCKET_AVATARS`
- 检查网络连接和端口(`RUSTFS_ENDPOINT`
- **注意**: 如果对象存储连接失败,服务仍可启动,但上传功能不可用
4. **邮件发送失败**
- 检查 `EMAIL_ENABLED=true`
- 验证SMTP服务器地址和端口
- 确认邮箱用户名和密码正确
- 检查邮件服务商是否需要开启SMTP
- 查看日志获取详细错误信息
5. **验证码相关问题**
- 验证码过期10分钟有效期
- 发送过于频繁1分钟限制
- Redis存储失败检查Redis连接
- 邮件未收到(检查垃圾邮件)
6. **JWT验证失败**
- 检查 `JWT_SECRET` 是否配置
- 验证令牌是否过期默认168小时
- 确认请求头中包含 `Authorization: Bearer <token>`
- Token格式是否正确
### 调试技巧
1. **查看日志**
```bash
# 实时查看日志
tail -f logs/app.log
# 搜索错误日志
grep "ERROR" logs/app.log
```
2. **测试Redis连接**
```bash
redis-cli -h localhost -p 6379 -a your_password
> PING
> KEYS *
```
3. **测试数据库连接**
```bash
psql -h localhost -U postgres -d carrotskin
\dt # 查看所有表
```
4. **测试邮件配置**
- 使用Swagger文档测试 `/api/v1/auth/send-code` 接口
- 检查邮件服务商是否限制发送频率
### 开发调试
启用详细日志:
```bash
# 在 .env 中设置
LOG_LEVEL=debug
SERVER_MODE=debug
```