9.4 KiB
9.4 KiB
JWT 认证系统文档
🔐 认证架构
Nebula 项目使用 JWT (JSON Web Token) 认证系统,提供完整的用户认证和授权功能。
核心特性
- ✅ JWT 双 Token 机制(Access Token + Refresh Token)
- ✅ 密码加密存储(bcrypt)
- ✅ 灵活的 Token 过期时间配置
- ✅ 中间件保护路由
- ✅ 角色权限支持(user/admin)
- ✅ 用户注册和登录
- ✅ 修改密码
- ✅ Token 刷新
📝 API 端点
1. 用户注册
POST /api/auth/register
Content-Type: application/json
{
"username": "testuser",
"email": "test@example.com",
"password": "password123"
}
响应:
{
"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. 用户登录
POST /api/auth/login
Content-Type: application/json
{
"username": "testuser",
"password": "password123"
}
响应: 同注册响应
3. 刷新 Token
POST /api/auth/refresh
Content-Type: application/json
{
"refresh_token": "eyJhbGciOiJIUzI1NiIs..."
}
响应:
{
"code": 0,
"message": "success",
"data": {
"access_token": "new_access_token",
"refresh_token": "new_refresh_token",
"expires_in": 7200
}
}
4. 获取当前用户信息
GET /api/auth/profile
Authorization: Bearer <access_token>
响应:
{
"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. 修改密码
POST /api/auth/change-password
Authorization: Bearer <access_token>
Content-Type: application/json
{
"old_password": "password123",
"new_password": "newpassword456"
}
响应:
{
"code": 0,
"message": "password changed successfully"
}
🧪 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 "❌ 未认证访问被拒绝(正确)"
}
🔧 配置
环境变量
# 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. 密码加密
// 使用 bcrypt 加密
hashedPassword, _ := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
// 验证密码
bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password))
2. Token 验证
- ✅ 签名验证
- ✅ 过期时间检查
- ✅ 算法验证(HMAC-SHA256)
3. 中间件保护
// 需要认证
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
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);
}
}
}
🚀 扩展功能
未来可添加
- Token 黑名单:退出登录时将 token 加入黑名单
- 双因素认证(2FA):增强安全性
- OAuth2 第三方登录:支持 GitHub、Google 等
- 权限细粒度控制:基于资源的权限管理
- 登录日志:记录登录历史和异常
- IP 白名单:限制访问来源
- 账号锁定:多次登录失败后锁定
✅ 测试验证
- ✅ 注册新用户
- ✅ 登录获取 token
- ✅ 使用 token 访问受保护的 API
- ✅ 刷新 token
- ✅ 修改密码
- ✅ 未认证访问被拒绝
完整的 JWT 认证系统已经实现并运行正常!🎉