🔐 Token 过期后的身份验证方案
🎯 问题场景
Token 过期后,如何验明用户身份?如果邮箱和密码不行怎么办?
✅ 当前支持的认证方式
1. 邮箱 + 密码(主要方式)
适用场景:
- ✅ 正常登录
- ✅ Token 过期后重新登录
- ✅ 首次登录
使用方式:
// 在登录页面
email: "user@example.com"
password: "YourPassword123"
如果不行的情况:
- ❌ 忘记密码
- ❌ 密码被修改
- ❌ 账户被锁定
2. 设备 ID(Device ID)
适用场景:
- ✅ 小智设备自动认证
- ✅ 已绑定设备的用户
- ✅ 无需密码的设备认证
工作原理:
# 后端支持通过设备ID自动创建或获取用户
if x_device_id:
user = await user_service.get_or_create_user_by_device(x_device_id)
return user.id
使用方式:
POST /api/v1/users/login
Headers:
X-Device-ID: your-device-id
优点:
- ✅ 无需密码
- ✅ 自动认证
- ✅ 适合设备场景
限制:
- ⚠️ 需要设备已绑定
- ⚠️ 仅适用于设备场景
3. API Key(API 密钥)
适用场景:
- ✅ 程序化访问
- ✅ 第三方集成
- ✅ 自动化脚本
工作原理:
# 后端支持通过 API Key 认证
if x_api_key:
user_id = await user_service.verify_api_key(x_api_key)
return user_id
使用方式:
GET /api/v1/users/me
Headers:
X-API-Key: mbe_xxxxxxxx_xxxxxxxx
创建 API Key:
POST /api/v1/users/api-key
Headers:
Authorization: Bearer <access_token>
优点:
- ✅ 长期有效(除非手动撤销)
- ✅ 适合自动化场景
- ✅ 可以创建多个 Key
限制:
- ⚠️ 需要先登录创建
- ⚠️ 不适合用户界面登录
🔄 Token 过期后的处理流程
场景 1: 正常情况(邮箱密码可用)
Token 过期
↓
提示"登录已过期,请重新登录"
↓
用户输入邮箱和密码
↓
验证成功,获得新 Token
↓
继续使用应用
场景 2: 忘记密码
当前状态:❌ 密码重置功能未实现
解决方案:
方案 A: 联系管理员
如果是在企业环境:
- 联系系统管理员
- 管理员可以重置密码
- 使用新密码登录
方案 B: 使用其他认证方式
如果有其他认证方式:
- 设备 ID:如果之前绑定过设备
- API Key:如果之前创建过 API Key
- 手机号:如果注册时使用了手机号
方案 C: 注册新账户
如果无法恢复:
- 使用新邮箱注册
- 重新开始使用
🛠️ 建议实现的密码重置功能
功能设计
1. 忘记密码流程
用户点击"忘记密码"
↓
输入注册邮箱
↓
发送密码重置链接到邮箱
↓
用户点击邮件中的链接
↓
设置新密码
↓
使用新密码登录
2. API 端点设计
# 请求重置密码
POST /api/v1/users/forgot-password
Body: {
"email": "user@example.com"
}
# 重置密码(使用重置令牌)
POST /api/v1/users/reset-password
Body: {
"token": "reset-token-from-email",
"new_password": "NewPassword123"
}
# 修改密码(需要登录)
POST /api/v1/users/change-password
Headers:
Authorization: Bearer <access_token>
Body: {
"old_password": "OldPassword123",
"new_password": "NewPassword123"
}
3. 安全考虑
- ✅ 重置链接有效期(如 1 小时)
- ✅ 重置链接只能使用一次
- ✅ 记录重置操作日志
- ✅ 防止暴力破解(限制请求频率)
🔍 当前可用的备选方案
方案 1: 使用设备 ID(如果适用)
前提条件:
- 之前绑定过设备
- 知道设备 ID
实现方式:
// 前端:使用设备 ID 登录
const deviceId = localStorage.getItem('device_id') || generateDeviceId();
const response = await fetch('/api/v1/users/login', {
method: 'POST',
headers: {
'X-Device-ID': deviceId,
'Content-Type': 'application/json'
}
});
方案 2: 使用 API Key(如果之前创建过)
前提条件:
- 之前创建过 API Key
- 保存了 API Key
实现方式:
// 使用 API Key 访问 API
const apiKey = 'mbe_xxxxxxxx_xxxxxxxx';
const response = await fetch('/api/v1/users/me', {
headers: {
'X-API-Key': apiKey
}
});
注意:API Key 主要用于 API 访问,不是用于界面登录。
方案 3: 使用手机号登录(如果注册时使用)
前提条件:
- 注册时使用了手机号
- 记得手机号
实现方式:
// 使用手机号登录
const response = await fetch('/api/v1/users/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
phone: '13800138000',
password: 'YourPassword123'
})
});
📋 身份验证方式对比
| 认证方式 | 适用场景 | 优点 | 缺点 | 是否需要密码 |
|---|---|---|---|---|
| 邮箱+密码 | 正常登录 | ✅ 通用 ✅ 安全 |
❌ 忘记密码无法恢复 | ✅ 是 |
| 手机号+密码 | 移动端 | ✅ 方便 ✅ 可短信验证 |
❌ 需要手机号 | ✅ 是 |
| 设备 ID | 设备场景 | ✅ 无需密码 ✅ 自动认证 |
❌ 需要绑定设备 | ❌ 否 |
| API Key | 程序化访问 | ✅ 长期有效 ✅ 适合自动化 |
❌ 不适合界面登录 | ❌ 否 |
| 密码重置 | 忘记密码 | ✅ 恢复账户 | ⚠️ 需要邮箱验证 | ❌ 否(重置时) |
💡 最佳实践建议
1. 预防措施
- ✅ 记住密码:使用密码管理器
- ✅ 绑定设备:绑定常用设备,可以使用设备 ID
- ✅ 创建 API Key:用于自动化场景
- ✅ 使用手机号:注册时绑定手机号
2. 如果忘记密码
当前:
- 尝试使用其他认证方式(设备 ID、API Key)
- 联系管理员(如果是企业账户)
- 注册新账户(最后手段)
未来(建议实现):
- 使用"忘记密码"功能
- 通过邮箱重置密码
- 使用新密码登录
3. Token 过期处理
自动刷新(推荐):
- ✅ 系统自动使用 Refresh Token 刷新
- ✅ 用户无感知
- ✅ 无需重新输入密码
手动重新登录(Refresh Token 也过期):
- ✅ 输入邮箱和密码
- ✅ 获得新的 Token
- ✅ 继续使用应用
🚀 未来改进建议
优先级 1: 密码重置功能
功能:
- 忘记密码流程
- 邮箱验证
- 密码重置链接
实现难度:中等 安全要求:高
优先级 2: 多因素认证(MFA)
功能:
- 短信验证码
- 邮箱验证码
- 应用验证器(TOTP)
实现难度:较高 安全要求:高
优先级 3: 社交登录
功能:
- Google 登录
- GitHub 登录
- 微信登录
实现难度:中等 安全要求:中等
📝 总结
Token 过期后的身份验证
- 主要方式:邮箱 + 密码
- 备选方式:
- 设备 ID(如果绑定过)
- API Key(如果创建过)
- 手机号(如果注册时使用)
如果邮箱密码不行
当前解决方案:
- ⚠️ 密码重置功能未实现
- ✅ 可以使用其他认证方式
- ✅ 可以联系管理员
- ✅ 可以注册新账户
建议:
- 🔄 实现密码重置功能
- 🔄 实现多因素认证
- 🔄 提供更多认证选项
最后更新:2026-02-08