init: 初始化项目
This commit is contained in:
405
docs/AUTH_JWT.md
Normal file
405
docs/AUTH_JWT.md
Normal file
@@ -0,0 +1,405 @@
|
||||
# JWT 认证系统文档
|
||||
|
||||
## 🔐 认证架构
|
||||
|
||||
Nebula 项目使用 **JWT (JSON Web Token)** 认证系统,提供完整的用户认证和授权功能。
|
||||
|
||||
### 核心特性
|
||||
|
||||
- ✅ **JWT 双 Token 机制**(Access Token + Refresh Token)
|
||||
- ✅ **密码加密存储**(bcrypt)
|
||||
- ✅ **灵活的 Token 过期时间配置**
|
||||
- ✅ **中间件保护路由**
|
||||
- ✅ **角色权限支持**(user/admin)
|
||||
- ✅ **用户注册和登录**
|
||||
- ✅ **修改密码**
|
||||
- ✅ **Token 刷新**
|
||||
|
||||
## 📝 API 端点
|
||||
|
||||
### 1. 用户注册
|
||||
|
||||
```http
|
||||
POST /api/auth/register
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"username": "testuser",
|
||||
"email": "test@example.com",
|
||||
"password": "password123"
|
||||
}
|
||||
```
|
||||
|
||||
**响应:**
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": {
|
||||
"user": {
|
||||
"id": "uuid",
|
||||
"username": "testuser",
|
||||
"email": "test@example.com",
|
||||
"role": "user",
|
||||
"createdAt": "2026-03-10T12:00:00Z",
|
||||
"updatedAt": "2026-03-10T12:00:00Z"
|
||||
},
|
||||
"tokens": {
|
||||
"access_token": "eyJhbGciOiJIUzI1NiIs...",
|
||||
"refresh_token": "eyJhbGciOiJIUzI1NiIs...",
|
||||
"expires_in": 7200
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 用户登录
|
||||
|
||||
```http
|
||||
POST /api/auth/login
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"username": "testuser",
|
||||
"password": "password123"
|
||||
}
|
||||
```
|
||||
|
||||
**响应:** 同注册响应
|
||||
|
||||
### 3. 刷新 Token
|
||||
|
||||
```http
|
||||
POST /api/auth/refresh
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"refresh_token": "eyJhbGciOiJIUzI1NiIs..."
|
||||
}
|
||||
```
|
||||
|
||||
**响应:**
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": {
|
||||
"access_token": "new_access_token",
|
||||
"refresh_token": "new_refresh_token",
|
||||
"expires_in": 7200
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 获取当前用户信息
|
||||
|
||||
```http
|
||||
GET /api/auth/profile
|
||||
Authorization: Bearer <access_token>
|
||||
```
|
||||
|
||||
**响应:**
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": {
|
||||
"id": "uuid",
|
||||
"username": "testuser",
|
||||
"email": "test@example.com",
|
||||
"role": "user",
|
||||
"createdAt": "2026-03-10T12:00:00Z",
|
||||
"updatedAt": "2026-03-10T12:00:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 修改密码
|
||||
|
||||
```http
|
||||
POST /api/auth/change-password
|
||||
Authorization: Bearer <access_token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"old_password": "password123",
|
||||
"new_password": "newpassword456"
|
||||
}
|
||||
```
|
||||
|
||||
**响应:**
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "password changed successfully"
|
||||
}
|
||||
```
|
||||
|
||||
## 🧪 PowerShell 测试示例
|
||||
|
||||
### 完整测试流程
|
||||
|
||||
```powershell
|
||||
# 1. 注册用户
|
||||
$registerBody = @{
|
||||
username = "testuser"
|
||||
email = "test@example.com"
|
||||
password = "password123"
|
||||
} | ConvertTo-Json
|
||||
|
||||
$registerResponse = Invoke-RestMethod -Uri "http://localhost:9050/api/auth/register" `
|
||||
-Method Post -Body $registerBody -ContentType "application/json"
|
||||
|
||||
Write-Host "✅ 注册成功!"
|
||||
Write-Host "用户 ID: $($registerResponse.data.user.id)"
|
||||
Write-Host "Access Token: $($registerResponse.data.tokens.access_token.Substring(0, 20))..."
|
||||
|
||||
# 保存 token
|
||||
$accessToken = $registerResponse.data.tokens.access_token
|
||||
$refreshToken = $registerResponse.data.tokens.refresh_token
|
||||
|
||||
# 2. 登录(测试)
|
||||
$loginBody = @{
|
||||
username = "testuser"
|
||||
password = "password123"
|
||||
} | ConvertTo-Json
|
||||
|
||||
$loginResponse = Invoke-RestMethod -Uri "http://localhost:9050/api/auth/login" `
|
||||
-Method Post -Body $loginBody -ContentType "application/json"
|
||||
|
||||
Write-Host "✅ 登录成功!"
|
||||
|
||||
# 3. 获取用户信息
|
||||
$headers = @{
|
||||
Authorization = "Bearer $accessToken"
|
||||
}
|
||||
|
||||
$profile = Invoke-RestMethod -Uri "http://localhost:9050/api/auth/profile" `
|
||||
-Method Get -Headers $headers
|
||||
|
||||
Write-Host "✅ 获取用户信息成功!"
|
||||
Write-Host "用户名: $($profile.data.username)"
|
||||
Write-Host "邮箱: $($profile.data.email)"
|
||||
|
||||
# 4. 创建应用(测试认证保护)
|
||||
$appBody = @{
|
||||
id = "test-app"
|
||||
name = "测试应用"
|
||||
description = "需要认证才能创建"
|
||||
} | ConvertTo-Json
|
||||
|
||||
$app = Invoke-RestMethod -Uri "http://localhost:9050/api/apps" `
|
||||
-Method Post -Body $appBody -ContentType "application/json" -Headers $headers
|
||||
|
||||
Write-Host "✅ 创建应用成功(认证有效)!"
|
||||
|
||||
# 5. 刷新 Token
|
||||
Start-Sleep -Seconds 2
|
||||
$refreshBody = @{
|
||||
refresh_token = $refreshToken
|
||||
} | ConvertTo-Json
|
||||
|
||||
$newTokens = Invoke-RestMethod -Uri "http://localhost:9050/api/auth/refresh" `
|
||||
-Method Post -Body $refreshBody -ContentType "application/json"
|
||||
|
||||
Write-Host "✅ Token 刷新成功!"
|
||||
|
||||
# 6. 修改密码
|
||||
$changePasswordBody = @{
|
||||
old_password = "password123"
|
||||
new_password = "newpassword456"
|
||||
} | ConvertTo-Json
|
||||
|
||||
$changeResult = Invoke-RestMethod -Uri "http://localhost:9050/api/auth/change-password" `
|
||||
-Method Post -Body $changePasswordBody -ContentType "application/json" -Headers $headers
|
||||
|
||||
Write-Host "✅ 密码修改成功!"
|
||||
|
||||
# 7. 测试未认证访问(应该失败)
|
||||
try {
|
||||
Invoke-RestMethod -Uri "http://localhost:9050/api/apps" -Method Get
|
||||
} catch {
|
||||
Write-Host "❌ 未认证访问被拒绝(正确)"
|
||||
}
|
||||
```
|
||||
|
||||
## 🔧 配置
|
||||
|
||||
### 环境变量
|
||||
|
||||
```bash
|
||||
# JWT 密钥(生产环境必须修改!)
|
||||
JWT_SECRET=your-secret-key-change-in-production
|
||||
|
||||
# Access Token 过期时间(默认 2 小时)
|
||||
JWT_ACCESS_TOKEN_DURATION=7200 # 秒
|
||||
# 或者
|
||||
JWT_ACCESS_TOKEN_DURATION=2h
|
||||
|
||||
# Refresh Token 过期时间(默认 7 天)
|
||||
JWT_REFRESH_TOKEN_DURATION=604800 # 秒
|
||||
# 或者
|
||||
JWT_REFRESH_TOKEN_DURATION=168h
|
||||
```
|
||||
|
||||
### 推荐配置
|
||||
|
||||
**开发环境:**
|
||||
- Access Token: 2 小时
|
||||
- Refresh Token: 7 天
|
||||
|
||||
**生产环境:**
|
||||
- Access Token: 15 分钟 - 1 小时
|
||||
- Refresh Token: 30 天
|
||||
- 强密钥(256位以上)
|
||||
|
||||
## 🛡️ 安全特性
|
||||
|
||||
### 1. 密码加密
|
||||
|
||||
```go
|
||||
// 使用 bcrypt 加密
|
||||
hashedPassword, _ := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
|
||||
// 验证密码
|
||||
bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password))
|
||||
```
|
||||
|
||||
### 2. Token 验证
|
||||
|
||||
- ✅ 签名验证
|
||||
- ✅ 过期时间检查
|
||||
- ✅ 算法验证(HMAC-SHA256)
|
||||
|
||||
### 3. 中间件保护
|
||||
|
||||
```go
|
||||
// 需要认证
|
||||
authRequired.Use(auth.JWTMiddleware(jwtService))
|
||||
|
||||
// 需要管理员权限
|
||||
adminRequired.Use(auth.JWTMiddleware(jwtService), auth.AdminMiddleware())
|
||||
```
|
||||
|
||||
## 📊 路由保护状态
|
||||
|
||||
### 公开路由(无需认证)
|
||||
|
||||
| 方法 | 路径 | 说明 |
|
||||
|------|------|------|
|
||||
| POST | /api/auth/register | 用户注册 |
|
||||
| POST | /api/auth/login | 用户登录 |
|
||||
| POST | /api/auth/refresh | 刷新 Token |
|
||||
| GET | /api/check-update | 检查更新 |
|
||||
|
||||
### 需要认证的路由
|
||||
|
||||
| 方法 | 路径 | 说明 |
|
||||
|------|------|------|
|
||||
| GET | /api/auth/profile | 获取用户信息 |
|
||||
| POST | /api/auth/change-password | 修改密码 |
|
||||
| GET/POST/PUT/DELETE | /api/apps/* | 应用管理 |
|
||||
| GET/POST/PUT/DELETE | /api/releases/* | 版本管理 |
|
||||
| GET/POST/PUT/DELETE | /api/assets/* | 资源管理 |
|
||||
|
||||
## 🔄 Token 刷新流程
|
||||
|
||||
```
|
||||
Client Server
|
||||
| |
|
||||
|-------- Request API --------->| (Access Token)
|
||||
|<----- 401 Token Expired ------| ❌
|
||||
| |
|
||||
|--- Refresh Token Request ---->| (Refresh Token)
|
||||
|<--- New Access Token ---------| ✅
|
||||
| |
|
||||
|-------- Request API --------->| (New Access Token)
|
||||
|<-------- Success -------------| ✅
|
||||
```
|
||||
|
||||
## 💡 客户端集成示例
|
||||
|
||||
### JavaScript/TypeScript
|
||||
|
||||
```typescript
|
||||
class AuthService {
|
||||
private accessToken: string | null = null;
|
||||
private refreshToken: string | null = null;
|
||||
|
||||
async login(username: string, password: string) {
|
||||
const response = await fetch('http://localhost:9050/api/auth/login', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username, password })
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
if (data.code === 0) {
|
||||
this.accessToken = data.data.tokens.access_token;
|
||||
this.refreshToken = data.data.tokens.refresh_token;
|
||||
|
||||
// 保存到 localStorage
|
||||
localStorage.setItem('access_token', this.accessToken);
|
||||
localStorage.setItem('refresh_token', this.refreshToken);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
async request(url: string, options: RequestInit = {}) {
|
||||
options.headers = {
|
||||
...options.headers,
|
||||
'Authorization': `Bearer ${this.accessToken}`
|
||||
};
|
||||
|
||||
let response = await fetch(url, options);
|
||||
|
||||
// Token 过期,尝试刷新
|
||||
if (response.status === 401) {
|
||||
await this.refresh();
|
||||
options.headers['Authorization'] = `Bearer ${this.accessToken}`;
|
||||
response = await fetch(url, options);
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
async refresh() {
|
||||
const response = await fetch('http://localhost:9050/api/auth/refresh', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ refresh_token: this.refreshToken })
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
if (data.code === 0) {
|
||||
this.accessToken = data.data.access_token;
|
||||
this.refreshToken = data.data.refresh_token;
|
||||
localStorage.setItem('access_token', this.accessToken);
|
||||
localStorage.setItem('refresh_token', this.refreshToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🚀 扩展功能
|
||||
|
||||
### 未来可添加
|
||||
|
||||
1. **Token 黑名单**:退出登录时将 token 加入黑名单
|
||||
2. **双因素认证(2FA)**:增强安全性
|
||||
3. **OAuth2 第三方登录**:支持 GitHub、Google 等
|
||||
4. **权限细粒度控制**:基于资源的权限管理
|
||||
5. **登录日志**:记录登录历史和异常
|
||||
6. **IP 白名单**:限制访问来源
|
||||
7. **账号锁定**:多次登录失败后锁定
|
||||
|
||||
## ✅ 测试验证
|
||||
|
||||
1. ✅ 注册新用户
|
||||
2. ✅ 登录获取 token
|
||||
3. ✅ 使用 token 访问受保护的 API
|
||||
4. ✅ 刷新 token
|
||||
5. ✅ 修改密码
|
||||
6. ✅ 未认证访问被拒绝
|
||||
|
||||
完整的 JWT 认证系统已经实现并运行正常!🎉
|
||||
Reference in New Issue
Block a user