chore: 初始化仓库,排除二进制文件和覆盖率文件
This commit is contained in:
564
README.md
Normal file
564
README.md
Normal file
@@ -0,0 +1,564 @@
|
||||
# CarrotSkin Backend
|
||||
|
||||
一个功能完善的Minecraft皮肤站后端系统,采用单体架构设计,基于Go语言和Gin框架开发。
|
||||
|
||||
## ✨ 核心功能
|
||||
|
||||
- ✅ **用户认证系统** - 注册、登录、JWT认证、积分系统
|
||||
- ✅ **邮箱验证系统** - 注册验证、找回密码、更换邮箱(基于Redis的验证码)
|
||||
- ✅ **材质管理系统** - 皮肤/披风上传、搜索、收藏、下载统计
|
||||
- ✅ **角色档案系统** - Minecraft角色创建、管理、RSA密钥生成
|
||||
- ✅ **文件存储** - MinIO/RustFS对象存储集成、预签名URL上传
|
||||
- ✅ **缓存系统** - Redis缓存、验证码存储、频率限制
|
||||
- ✅ **权限管理** - Casbin RBAC权限控制
|
||||
- ✅ **数据审计** - 登录日志、操作审计、下载记录
|
||||
|
||||
## 项目结构
|
||||
|
||||
```
|
||||
backend/
|
||||
├── cmd/ # 应用程序入口
|
||||
│ └── server/ # 主服务器入口
|
||||
│ └── main.go # 服务初始化、路由注册
|
||||
├── internal/ # 私有应用代码
|
||||
│ ├── handler/ # HTTP处理器(函数式)
|
||||
│ │ ├── routes.go # 路由注册
|
||||
│ │ ├── auth_handler.go
|
||||
│ │ ├── user_handler.go
|
||||
│ │ └── ...
|
||||
│ ├── service/ # 业务逻辑服务(函数式)
|
||||
│ │ ├── common.go # 公共声明(jsoniter等)
|
||||
│ │ ├── user_service.go
|
||||
│ │ └── ...
|
||||
│ ├── repository/ # 数据访问层(函数式)
|
||||
│ │ ├── user_repository.go
|
||||
│ │ └── ...
|
||||
│ ├── 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+
|
||||
- **框架**: Gin Web Framework
|
||||
- **数据库**: PostgreSQL 15+ (GORM ORM)
|
||||
- **缓存**: Redis 6.0+
|
||||
- **存储**: RustFS/MinIO (S3兼容对象存储)
|
||||
- **权限**: Casbin RBAC
|
||||
- **日志**: Zap (结构化日志)
|
||||
- **配置**: 环境变量 (.env) + Viper
|
||||
- **JSON**: jsoniter (高性能JSON序列化)
|
||||
- **文档**: Swagger/OpenAPI 3.0
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 环境要求
|
||||
|
||||
- Go 1.21或更高版本
|
||||
- PostgreSQL 15或更高版本
|
||||
- Redis 6.0或更高版本
|
||||
- RustFS 或其他 S3 兼容对象存储服务
|
||||
|
||||
### 安装和运行
|
||||
|
||||
1. **克隆项目**
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd CarrotSkin/backend
|
||||
```
|
||||
|
||||
2. **安装依赖**
|
||||
```bash
|
||||
go mod download
|
||||
```
|
||||
|
||||
3. **配置环境**
|
||||
```bash
|
||||
# 复制环境变量文件
|
||||
cp .env.example .env
|
||||
# 编辑 .env 文件配置数据库、RustFS等服务连接信息
|
||||
```
|
||||
|
||||
**注意**:项目完全依赖 `.env` 文件进行配置,不再使用 YAML 配置文件,便于 Docker 容器化部署。
|
||||
|
||||
4. **初始化数据库**
|
||||
```bash
|
||||
# 创建数据库
|
||||
createdb carrotskin
|
||||
# 或者使用PostgreSQL客户端
|
||||
psql -h localhost -U postgres -c "CREATE DATABASE carrotskin;"
|
||||
```
|
||||
|
||||
> 💡 **提示**: 项目使用 GORM 的 `AutoMigrate` 功能自动创建和更新数据库表结构,无需手动执行SQL脚本。首次启动时会自动创建所有表。
|
||||
|
||||
5. **运行服务**
|
||||
|
||||
方式一:使用启动脚本(推荐)
|
||||
```bash
|
||||
# Linux/Mac
|
||||
chmod +x start.sh
|
||||
./start.sh
|
||||
|
||||
# Windows
|
||||
start.bat
|
||||
```
|
||||
|
||||
方式二:直接运行
|
||||
```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位数字)
|
||||
- 验证码存储(Redis,10分钟有效期,通过 `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
|
||||
# 安装依赖
|
||||
go mod download
|
||||
|
||||
# 配置环境变量(创建.env文件或直接export)
|
||||
cp .env.example .env
|
||||
# 编辑 .env 文件
|
||||
|
||||
# 启动服务
|
||||
# 方式1: 使用启动脚本
|
||||
./start.sh # Linux/Mac
|
||||
start.bat # Windows
|
||||
|
||||
# 方式2: 直接运行
|
||||
go run cmd/server/main.go
|
||||
```
|
||||
|
||||
**首次启动**:
|
||||
- 会自动执行数据库迁移(AutoMigrate),创建所有表结构
|
||||
- 如果对象存储未配置,会记录警告但服务仍可启动
|
||||
- 检查日志确认所有服务初始化成功
|
||||
|
||||
### 生产部署
|
||||
|
||||
```bash
|
||||
# 构建二进制文件
|
||||
go build -o carrotskin-server cmd/server/main.go
|
||||
|
||||
# 运行服务
|
||||
./carrotskin-server
|
||||
```
|
||||
|
||||
### Docker部署
|
||||
|
||||
```bash
|
||||
# 构建镜像
|
||||
docker build -t carrotskin-backend:latest .
|
||||
|
||||
# 启动服务
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
## 故障排查
|
||||
|
||||
### 常见问题
|
||||
|
||||
1. **数据库连接失败**
|
||||
- 检查 `.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
|
||||
```
|
||||
Reference in New Issue
Block a user