feat(auth): 添加二维码登录功能- 实现了二维码登录的前端组件和API接口

- 添加了二维码登录的后端逻辑和数据库设计
- 编写了详细的使用说明和接口文档
- 提供了演示页面和测试工具
This commit is contained in:
2025-09-08 14:57:57 +08:00
parent 7b6fac7c41
commit a67162ee06
12 changed files with 2350 additions and 2 deletions

212
docs/qr-login-api.md Normal file
View File

@@ -0,0 +1,212 @@
# 二维码登录API接口文档已适配后端
## 概述
二维码登录功能允许用户通过手机APP或小程序扫描Web端生成的二维码来完成登录提供更便捷和安全的登录体验。
**后端实现状态:** ✅ 已完成
**前端适配状态:** ✅ 已完成
## 接口列表
### 1. 生成登录二维码
**接口地址:** `POST /api/qr-login/generate`
**请求参数:**
**响应数据:**
```json
{
"code": 0,
"message": "生成成功",
"data": {
"token": "abc123def456",
"qrCode": "qr-login:abc123def456",
"expiresIn": 300
}
}
```
**字段说明:**
- `token`: 二维码唯一标识token用于后续状态查询
- `qrCode`: 二维码内容(后端生成的原始内容)
- `expiresIn`: 过期时间默认300秒5分钟
### 2. 检查二维码状态
**接口地址:** `GET /api/qr-login/status/{token}`
**请求参数:**
- `token`: 二维码token路径参数
**响应数据:**
```json
{
"code": 0,
"message": "查询成功",
"data": {
"status": "pending",
"expiresIn": 280
}
}
```
**状态说明:**
- `pending`: 等待扫码
- `scanned`: 已扫码,等待确认
- `confirmed`: 已确认登录
- `expired`: 已过期
**登录成功时的响应:**
```json
{
"code": 0,
"message": "登录成功",
"data": {
"status": "confirmed",
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"userInfo": {
"userId": 1,
"username": "admin",
"nickname": "管理员",
"avatar": "https://example.com/avatar.jpg"
},
"expiresIn": 60
}
}
```
### 3. 扫码标记
**接口地址:** `POST /api/qr-login/scan/{token}`
**请求参数:**
- `token`: 二维码token路径参数
**响应数据:**
```json
{
"code": 0,
"message": "操作成功",
"data": true
}
```
### 4. 确认登录
**接口地址:** `POST /api/qr-login/confirm`
**请求参数:**
```json
{
"token": "abc123def456",
"userId": 1,
"platform": "web"
}
```
**响应数据:**
```json
{
"code": 0,
"message": "确认成功",
"data": {
"status": "confirmed",
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"userInfo": {
"userId": 1,
"username": "admin",
"nickname": "管理员"
},
"expiresIn": 60
}
}
```
### 5. 微信小程序确认登录
**接口地址:** `POST /api/qr-login/wechat-confirm`
**请求参数:**
```json
{
"token": "abc123def456",
"userId": 1,
"platform": "miniprogram",
"wechatInfo": {
"openid": "wx_openid_123",
"unionid": "wx_unionid_456",
"nickname": "微信用户",
"avatar": "https://wx.qlogo.cn/..."
}
}
```
**响应数据:**
```json
{
"code": 0,
"message": "微信小程序登录确认成功",
"data": {
"status": "confirmed",
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"userInfo": {...},
"expiresIn": 60
}
}
```
## 实现流程
### Web端流程
1. 用户点击扫码登录
2. 前端调用 `/qr-login/generate` 生成二维码
3. 显示二维码给用户
4. 前端轮询调用 `/qr-login/status` 检查状态
5. 当状态为 `confirmed`获取token完成登录
### 移动端流程:
1. 用户扫描二维码,跳转到确认页面
2. 页面加载时调用 `/qr-login/scan` 标记已扫码
3. 用户点击确认后调用 `/qr-login/confirm` 确认登录
4. 或用户点击取消后调用 `/qr-login/cancel` 取消登录
## 安全考虑
1. **二维码有效期**建议设置5分钟有效期过期后需要重新生成
2. **一次性使用**:每个二维码只能使用一次,确认或取消后立即失效
3. **用户验证**:移动端需要验证用户的登录状态
4. **IP限制**可以记录生成二维码的IP限制异地登录
5. **频率限制**限制同一IP生成二维码的频率
## 数据库设计建议
```sql
CREATE TABLE qr_login_records (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
qr_code_key VARCHAR(64) UNIQUE NOT NULL COMMENT '二维码唯一标识',
status ENUM('waiting', 'scanned', 'confirmed', 'expired', 'cancelled') DEFAULT 'waiting' COMMENT '状态',
user_id BIGINT NULL COMMENT '扫码用户ID',
client_ip VARCHAR(45) COMMENT '客户端IP',
user_agent TEXT COMMENT '用户代理',
expire_time DATETIME NOT NULL COMMENT '过期时间',
scan_time DATETIME NULL COMMENT '扫码时间',
confirm_time DATETIME NULL COMMENT '确认时间',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_qr_code_key (qr_code_key),
INDEX idx_status (status),
INDEX idx_expire_time (expire_time)
);
```
## 错误码说明
- `0`: 成功
- `400`: 参数错误
- `401`: 未授权
- `404`: 二维码不存在
- `410`: 二维码已过期
- `429`: 请求过于频繁
- `500`: 服务器内部错误

View File

@@ -0,0 +1,262 @@
# 二维码登录功能设置指南
## 概述
本指南将帮助您设置和测试二维码登录功能。后端Java代码已经完成前端Vue代码已经适配完成。
## 🎯 功能状态
-**后端实现**: Java Spring Boot (已完成)
-**前端适配**: Vue 3 + TypeScript (已完成)
-**接口对接**: API接口已适配
-**测试页面**: 提供完整的测试工具
## 🚀 快速开始
### 1. 启动后端服务
确保您的Java后端服务正在运行并且包含以下文件
```
java/auto/
├── controller/QrLoginController.java
├── service/QrLoginService.java
├── service/impl/QrLoginServiceImpl.java
└── dto/
├── QrLoginGenerateResponse.java
├── QrLoginStatusResponse.java
├── QrLoginConfirmRequest.java
└── QrLoginData.java
```
### 2. 启动前端服务
```bash
npm run dev
# 或
yarn dev
```
### 3. 测试接口连通性
访问接口测试页面:
```
http://localhost:3000/qr-test
```
按照以下步骤测试:
1. **生成二维码** - 点击"生成二维码"按钮
2. **检查状态** - 开启"自动检查"开关
3. **模拟扫码** - 点击"模拟扫码"按钮
4. **确认登录** - 输入用户ID点击"确认登录"
## 📱 使用流程
### Web端操作
1. **进入登录页面**
```
http://localhost:3000/login
```
2. **切换到扫码登录**
- 点击右上角的二维码图标
- 系统自动生成二维码
3. **等待扫码**
- 二维码有效期5分钟
- 系统每2秒检查一次状态
### 移动端操作
1. **扫描二维码**
- 使用手机扫描Web端的二维码
- 或直接访问二维码中的URL
2. **确认登录**
```
http://localhost:3000/qr-confirm?qrCodeKey=abc123def456
```
- 显示用户信息和设备信息
- 点击"确认登录"完成登录
## 🔧 配置说明
### 后端配置
在 `application.yml` 中配置JWT相关参数
```yaml
config:
jwt:
secret: websoft-jwt-secret-key-2025
expire: 86400 # 24小时
```
### 前端配置
在 `src/config/setting.ts` 中确认API地址
```typescript
export const SERVER_API_URL = 'http://localhost:8080';
```
## 🧪 测试场景
### 1. 正常登录流程
1. Web端生成二维码
2. 移动端扫码
3. 移动端确认登录
4. Web端自动登录成功
### 2. 过期场景
1. 生成二维码后等待5分钟
2. 二维码自动过期
3. 点击刷新重新生成
### 3. 取消场景
1. 移动端扫码后点击取消
2. Web端继续等待新的扫码
## 🔍 调试方法
### 1. 查看网络请求
打开浏览器开发者工具 → Network面板
- `POST /api/qr-login/generate` - 生成二维码
- `GET /api/qr-login/status/{token}` - 检查状态
- `POST /api/qr-login/scan/{token}` - 扫码标记
- `POST /api/qr-login/confirm` - 确认登录
### 2. 查看控制台日志
前端会输出详细的调试信息:
```javascript
// 开启调试模式
localStorage.setItem('debug', 'qr-login');
```
### 3. 后端日志
查看后端控制台输出:
```
生成扫码登录token: abc123def456
用户 admin 确认扫码登录token: abc123def456
扫码登录token abc123def456 状态更新为已扫码
```
## 🛠️ 常见问题
### 1. 二维码生成失败
**可能原因:**
- 后端服务未启动
- Redis服务未启动
- 网络连接问题
**解决方法:**
- 检查后端服务状态
- 确认Redis连接正常
- 查看控制台错误信息
### 2. 扫码后无响应
**可能原因:**
- 二维码已过期
- 用户未登录
- 网络请求失败
**解决方法:**
- 刷新二维码
- 确认用户登录状态
- 检查网络连接
### 3. 确认登录失败
**可能原因:**
- 用户ID不存在
- 用户状态异常
- JWT配置错误
**解决方法:**
- 检查用户数据
- 确认用户状态正常
- 验证JWT配置
## 📋 API接口清单
| 接口 | 方法 | 路径 | 说明 |
|------|------|------|------|
| 生成二维码 | POST | `/api/qr-login/generate` | 生成登录二维码 |
| 检查状态 | GET | `/api/qr-login/status/{token}` | 检查二维码状态 |
| 扫码标记 | POST | `/api/qr-login/scan/{token}` | 标记已扫码 |
| 确认登录 | POST | `/api/qr-login/confirm` | 确认登录 |
| 微信确认 | POST | `/api/qr-login/wechat-confirm` | 微信小程序确认 |
## 🔐 安全特性
1. **时效控制**: 二维码5分钟自动过期
2. **一次性使用**: 每个二维码只能使用一次
3. **状态验证**: 严格的状态流转控制
4. **JWT安全**: 使用JWT进行身份验证
5. **Redis存储**: 使用Redis存储临时数据
## 📈 性能优化
1. **轮询间隔**: 前端每2秒检查一次状态
2. **缓存策略**: Redis自动过期清理
3. **并发控制**: 支持多用户同时使用
4. **资源清理**: 及时清理过期数据
## 🎨 自定义配置
### 修改过期时间
在后端常量中修改:
```java
// 默认5分钟 = 300秒
private static final Long QR_LOGIN_TOKEN_TTL = 300L;
```
### 修改检查间隔
在前端组件中修改:
```typescript
// 默认2秒检查一次
}, 2000);
```
### 修改二维码样式
在前端组件中修改:
```vue
<ele-qr-code-svg :value="qrCodeData" :size="200" />
```
## 📞 技术支持
如果遇到问题,请:
1. 查看控制台错误信息
2. 检查网络请求状态
3. 确认后端服务正常
4. 查看本文档的常见问题部分
## 🔄 更新日志
### v1.0.0 (当前版本)
- ✅ 完成后端Java实现
- ✅ 完成前端Vue适配
- ✅ 提供完整测试工具
- ✅ 支持Web端和移动端
- ✅ 支持微信小程序登录

234
docs/qr-login-usage.md Normal file
View File

@@ -0,0 +1,234 @@
# 二维码登录功能使用说明
## 功能概述
二维码登录功能为用户提供了一种便捷的登录方式用户可以通过手机APP或小程序扫描Web端生成的二维码来快速登录管理后台无需输入用户名和密码。
## 功能特点
1. **便捷性**:无需输入账号密码,扫码即可登录
2. **安全性**:二维码具有时效性,过期自动失效
3. **实时性**:支持实时状态更新,用户体验流畅
4. **跨平台**支持APP和小程序扫码登录
## 使用流程
### Web端操作流程
1. **进入登录页面**
- 访问系统登录页面
- 点击右上角的二维码图标切换到扫码登录模式
2. **生成二维码**
- 系统自动生成登录二维码
- 二维码有效期为5分钟
3. **等待扫码**
- 使用手机APP或小程序扫描二维码
- 系统实时检测扫码状态
4. **完成登录**
- 用户在手机端确认登录后Web端自动完成登录
- 跳转到系统首页
### 移动端操作流程
1. **扫描二维码**
- 打开手机APP或小程序
- 使用扫码功能扫描Web端的二维码
2. **确认登录**
- 跳转到登录确认页面
- 显示用户信息和设备信息
- 点击"确认登录"按钮
3. **完成登录**
- 系统完成登录验证
- Web端自动登录成功
## 组件使用
### 在登录页面中集成
```vue
<template>
<div v-if="loginType === 'scan'">
<QrLogin
@loginSuccess="onQrLoginSuccess"
@loginError="onQrLoginError"
/>
</div>
</template>
<script setup>
import QrLogin from '@/components/QrLogin/index.vue';
const onQrLoginSuccess = (token) => {
// 处理登录成功
localStorage.setItem('access_token', token);
// 跳转到首页
router.push('/');
};
const onQrLoginError = (error) => {
// 处理登录错误
message.error(error);
};
</script>
```
### 独立使用二维码组件
```vue
<template>
<QrLogin
@loginSuccess="handleLoginSuccess"
@loginError="handleLoginError"
/>
</template>
<script setup>
import QrLogin from '@/components/QrLogin/index.vue';
const handleLoginSuccess = (token) => {
console.log('登录成功token:', token);
};
const handleLoginError = (error) => {
console.error('登录失败:', error);
};
</script>
```
## API接口
### 前端API调用
```typescript
import {
generateQrCode,
checkQrCodeStatus,
confirmQrLogin,
cancelQrLogin
} from '@/api/passport/qrLogin';
// 生成二维码
const qrData = await generateQrCode();
// 检查状态
const status = await checkQrCodeStatus(qrCodeKey);
// 确认登录(移动端)
await confirmQrLogin(qrCodeKey, userToken);
// 取消登录(移动端)
await cancelQrLogin(qrCodeKey);
```
## 状态说明
| 状态 | 说明 | 显示内容 |
|------|------|----------|
| loading | 正在生成二维码 | 加载动画 + "正在生成二维码..." |
| active | 二维码有效,等待扫码 | 二维码 + "请使用手机APP或小程序扫码登录" |
| scanned | 已扫码,等待确认 | 成功图标 + "扫码成功,请在手机上确认登录" |
| expired | 二维码已过期 | 过期图标 + "二维码已过期" + 刷新按钮 |
| error | 生成失败 | 错误图标 + 错误信息 + 重新生成按钮 |
## 配置说明
### 二维码配置
```typescript
// 二维码大小
const qrCodeSize = 200; // 像素
// 过期时间
const expireTime = 300; // 5分钟
// 检查间隔
const checkInterval = 2000; // 2秒
```
### 样式自定义
```less
// 自定义二维码容器样式
.qr-login-container {
padding: 20px;
text-align: center;
.qr-code-wrapper {
min-height: 250px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
}
```
## 安全注意事项
1. **二维码时效性**
- 二维码默认5分钟过期
- 过期后需要重新生成
2. **一次性使用**
- 每个二维码只能使用一次
- 登录成功或取消后立即失效
3. **用户验证**
- 移动端需要用户已登录状态
- 验证用户身份后才能确认登录
4. **网络安全**
- 使用HTTPS协议传输
- 敏感信息加密处理
## 故障排除
### 常见问题
1. **二维码生成失败**
- 检查网络连接
- 确认后端API接口正常
- 查看浏览器控制台错误信息
2. **扫码后无响应**
- 检查移动端网络连接
- 确认二维码未过期
- 检查用户登录状态
3. **登录确认失败**
- 检查用户权限
- 确认token有效性
- 查看后端日志
### 调试方法
1. **开启控制台调试**
```javascript
// 在浏览器控制台查看详细日志
localStorage.setItem('debug', 'qr-login');
```
2. **网络请求监控**
- 使用浏览器开发者工具监控网络请求
- 检查API响应状态和数据
3. **状态跟踪**
- 观察二维码状态变化
- 记录状态转换时间点
## 更新日志
### v1.0.0
- 初始版本发布
- 支持基本的二维码登录功能
- 包含Web端和移动端完整流程
### 后续计划
- 支持多设备同时登录
- 添加登录设备管理
- 优化用户体验和界面设计