diff --git a/demo/EMAIL_VERIFICATION_SIMPLE.md b/demo/EMAIL_VERIFICATION_SIMPLE.md
new file mode 100644
index 0000000..1bf67c5
--- /dev/null
+++ b/demo/EMAIL_VERIFICATION_SIMPLE.md
@@ -0,0 +1,100 @@
+# 邮箱验证码登录 - 简化版本
+
+## 功能说明
+
+已实现基于邮箱验证码的登录功能,**无需Redis**,使用内存存储验证码。
+
+## 技术实现
+
+### 存储方式
+- **验证码存储**:使用 `ConcurrentHashMap` 内存存储
+- **频率限制**:使用 `ConcurrentHashMap` 存储发送时间
+- **自动过期**:使用 `ScheduledExecutorService` 定时清理过期验证码
+
+### 安全机制
+- ✅ 验证码6位数字
+- ✅ 5分钟有效期
+- ✅ 60秒发送频率限制
+- ✅ 一次性使用(验证后删除)
+- ✅ 线程安全存储
+
+## 测试方法
+
+### 1. 启动应用
+```bash
+cd demo
+mvn spring-boot:run
+```
+
+### 2. 测试API
+
+#### 发送验证码
+```bash
+curl -X POST http://localhost:8080/api/verification/email/send \
+ -H "Content-Type: application/json" \
+ -d '{"email": "test@example.com"}'
+```
+
+**响应**:
+```json
+{
+ "success": true,
+ "message": "验证码发送成功"
+}
+```
+
+**注意**:验证码会在应用日志中输出,格式如:
+```
+模拟发送邮件验证码到: test@example.com, 验证码: 123456
+```
+
+#### 验证码登录
+```bash
+curl -X POST http://localhost:8080/api/auth/login/email \
+ -H "Content-Type: application/json" \
+ -d '{"email": "test@example.com", "code": "123456"}'
+```
+
+**成功响应**:
+```json
+{
+ "success": true,
+ "message": "登录成功",
+ "data": {
+ "user": {
+ "id": 1,
+ "username": "test",
+ "email": "test@example.com",
+ "role": "ROLE_USER",
+ "points": 100
+ },
+ "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
+ }
+}
+```
+
+## 优势
+
+1. **无需外部依赖**:不需要安装Redis
+2. **简单部署**:直接运行Spring Boot应用即可
+3. **开发友好**:验证码在日志中可见,便于测试
+4. **性能良好**:内存存储速度快
+5. **线程安全**:使用ConcurrentHashMap保证并发安全
+
+## 限制
+
+1. **单机部署**:验证码存储在内存中,多实例部署时无法共享
+2. **重启丢失**:应用重启后验证码会丢失
+3. **内存占用**:大量验证码会占用内存(通常不是问题)
+
+## 生产环境建议
+
+如果需要生产环境部署,建议:
+
+1. **使用Redis**:多实例部署时共享验证码
+2. **配置真实邮件服务**:集成腾讯云SES或其他邮件服务
+3. **添加监控**:监控验证码发送频率和成功率
+
+## 下一步
+
+现在可以开始修改前端登录页面,实现邮箱验证码登录界面。
diff --git a/demo/EMAIL_VERIFICATION_SUMMARY.md b/demo/EMAIL_VERIFICATION_SUMMARY.md
new file mode 100644
index 0000000..782cc99
--- /dev/null
+++ b/demo/EMAIL_VERIFICATION_SUMMARY.md
@@ -0,0 +1,192 @@
+# 邮箱验证码登录功能总结
+
+## 功能概述
+
+已实现基于邮箱验证码的登录功能,用户可以通过邮箱接收验证码进行登录,无需记住密码。
+
+## 后端实现
+
+### 1. 核心组件
+
+#### VerificationCodeService
+- **功能**:验证码生成、发送、验证
+- **位置**:`src/main/java/com/example/demo/service/VerificationCodeService.java`
+- **主要方法**:
+ - `generateVerificationCode()`: 生成6位数字验证码
+ - `sendEmailVerificationCode(String email)`: 发送邮件验证码
+ - `verifyEmailCode(String email, String code)`: 验证邮箱验证码
+
+#### VerificationCodeController
+- **功能**:验证码相关API接口
+- **位置**:`src/main/java/com/example/demo/controller/VerificationCodeController.java`
+- **API接口**:
+ - `POST /api/verification/email/send`: 发送邮件验证码
+ - `POST /api/verification/email/verify`: 验证邮件验证码
+
+#### AuthApiController (扩展)
+- **功能**:认证相关API,新增邮箱验证码登录
+- **位置**:`src/main/java/com/example/demo/controller/AuthApiController.java`
+- **新增接口**:
+ - `POST /api/auth/login/email`: 邮箱验证码登录
+
+### 2. 数据存储
+
+#### Redis配置
+- **用途**:存储验证码和发送频率限制
+- **配置类**:`src/main/java/com/example/demo/config/RedisConfig.java`
+- **存储结构**:
+ - `email_code:{email}`: 存储验证码,5分钟过期
+ - `email_rate_limit:{email}`: 发送频率限制,60秒过期
+
+#### 数据库扩展
+- **UserRepository**: 新增 `findByPhone()` 和 `existsByPhone()` 方法
+- **UserService**: 新增 `findByPhone()` 方法
+
+### 3. 安全机制
+
+#### 验证码安全
+- **长度**:6位数字
+- **有效期**:5分钟
+- **发送频率限制**:同一邮箱60秒内只能发送一次
+- **一次性使用**:验证成功后立即删除
+
+#### 用户验证
+- **邮箱格式验证**:前端和后端双重验证
+- **用户存在性检查**:登录时验证用户是否存在
+- **JWT Token生成**:验证成功后生成访问令牌
+
+## API接口文档
+
+### 1. 发送邮件验证码
+
+**请求**
+```http
+POST /api/verification/email/send
+Content-Type: application/json
+
+{
+ "email": "user@example.com"
+}
+```
+
+**响应**
+```json
+{
+ "success": true,
+ "message": "验证码发送成功"
+}
+```
+
+### 2. 验证邮件验证码
+
+**请求**
+```http
+POST /api/verification/email/verify
+Content-Type: application/json
+
+{
+ "email": "user@example.com",
+ "code": "123456"
+}
+```
+
+**响应**
+```json
+{
+ "success": true,
+ "message": "验证码验证成功"
+}
+```
+
+### 3. 邮箱验证码登录
+
+**请求**
+```http
+POST /api/auth/login/email
+Content-Type: application/json
+
+{
+ "email": "user@example.com",
+ "code": "123456"
+}
+```
+
+**响应**
+```json
+{
+ "success": true,
+ "message": "登录成功",
+ "data": {
+ "user": {
+ "id": 1,
+ "username": "user",
+ "email": "user@example.com",
+ "role": "ROLE_USER",
+ "points": 100
+ },
+ "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
+ }
+}
+```
+
+## 配置说明
+
+### 1. 腾讯云配置 (可选)
+- **配置文件**:`src/main/resources/application-tencent.properties`
+- **用途**:集成腾讯云邮件推送服务
+- **当前状态**:暂时使用模拟发送,实际部署时需要配置
+
+### 2. Redis配置
+- **默认配置**:localhost:6379
+- **用途**:验证码存储和频率限制
+- **生产环境**:建议配置密码和持久化
+
+## 测试方法
+
+### 1. 启动服务
+```bash
+# 启动Redis
+redis-server
+
+# 启动应用
+mvn spring-boot:run
+```
+
+### 2. 测试流程
+```bash
+# 1. 发送验证码
+curl -X POST http://localhost:8080/api/verification/email/send \
+ -H "Content-Type: application/json" \
+ -d '{"email": "test@example.com"}'
+
+# 2. 查看日志获取验证码(当前为模拟发送)
+# 3. 使用验证码登录
+curl -X POST http://localhost:8080/api/auth/login/email \
+ -H "Content-Type: application/json" \
+ -d '{"email": "test@example.com", "code": "123456"}'
+```
+
+## 待完成功能
+
+### 1. 腾讯云集成
+- [ ] 配置腾讯云SES服务
+- [ ] 实现真实的邮件发送
+- [ ] 配置邮件模板
+
+### 2. 前端集成
+- [ ] 修改登录页面支持邮箱验证码
+- [ ] 添加验证码输入框
+- [ ] 实现倒计时功能
+- [ ] 添加错误处理
+
+### 3. 安全增强
+- [ ] 添加图形验证码
+- [ ] 实现IP限制
+- [ ] 添加设备指纹识别
+
+## 注意事项
+
+1. **开发环境**:当前使用模拟邮件发送,验证码会在日志中输出
+2. **生产环境**:需要配置真实的邮件服务
+3. **安全考虑**:验证码有效期和发送频率限制已实现
+4. **扩展性**:可以轻松添加短信验证码等其他验证方式
diff --git a/demo/TENCENT_CLOUD_SETUP.md b/demo/TENCENT_CLOUD_SETUP.md
new file mode 100644
index 0000000..0f4fb92
--- /dev/null
+++ b/demo/TENCENT_CLOUD_SETUP.md
@@ -0,0 +1,119 @@
+# 腾讯云邮箱验证码登录配置指南
+
+## 1. 腾讯云服务开通
+
+### 1.1 开通邮件推送服务(SES)
+1. 登录腾讯云控制台
+2. 进入"邮件推送"服务
+3. 开通邮件推送服务
+4. 配置发件人邮箱
+5. 申请邮件模板
+
+### 1.2 获取API密钥
+1. 进入"访问管理" -> "API密钥管理"
+2. 创建密钥,获取SecretId和SecretKey
+
+## 2. 配置参数
+
+### 2.1 修改配置文件
+编辑 `src/main/resources/application-tencent.properties`:
+
+```properties
+# 腾讯云配置
+tencent.cloud.secret-id=你的SecretId
+tencent.cloud.secret-key=你的SecretKey
+
+# 邮件推送服务配置
+tencent.cloud.ses.region=ap-beijing
+tencent.cloud.ses.from-email=你的发件人邮箱
+tencent.cloud.ses.from-name=你的应用名称
+tencent.cloud.ses.template-id=你的邮件模板ID
+```
+
+### 2.2 邮件模板示例
+```html
+
+
+
+
+ 验证码
+
+
+ 验证码
+ 您的验证码是:{{code}}
+ 请在5分钟内输入,如非本人操作,请忽略此邮件。
+
+
+```
+
+## 3. Redis配置
+
+### 3.1 安装Redis
+- Windows: 下载Redis for Windows
+- Linux: `sudo apt-get install redis-server`
+- macOS: `brew install redis`
+
+### 3.2 启动Redis
+```bash
+redis-server
+```
+
+### 3.3 配置Redis连接
+修改 `application-tencent.properties` 中的Redis配置:
+```properties
+spring.data.redis.host=localhost
+spring.data.redis.port=6379
+spring.data.redis.password=
+spring.data.redis.database=0
+```
+
+## 4. 测试验证码功能
+
+### 4.1 发送邮件验证码
+```bash
+curl -X POST http://localhost:8080/api/verification/email/send \
+ -H "Content-Type: application/json" \
+ -d '{"email": "test@example.com"}'
+```
+
+### 4.2 验证码登录
+```bash
+# 邮箱验证码登录
+curl -X POST http://localhost:8080/api/auth/login/email \
+ -H "Content-Type: application/json" \
+ -d '{"email": "test@example.com", "code": "123456"}'
+```
+
+## 5. 安全注意事项
+
+1. **API密钥安全**:不要将SecretId和SecretKey提交到代码仓库
+2. **验证码有效期**:验证码5分钟过期
+3. **发送频率限制**:同一邮箱60秒内只能发送一次
+4. **验证码长度**:6位数字验证码
+5. **Redis安全**:生产环境建议设置Redis密码
+
+## 6. 故障排除
+
+### 6.1 常见错误
+- `TencentCloudSDKException`: 检查API密钥和配置
+- `Redis连接失败`: 检查Redis服务是否启动
+- `验证码发送失败`: 检查腾讯云服务配置
+
+### 6.2 日志查看
+查看应用日志中的验证码相关日志:
+```bash
+tail -f logs/application.log | grep "验证码"
+```
+
+## 7. 生产环境部署
+
+### 7.1 环境变量配置
+```bash
+export TENCENT_SECRET_ID=你的SecretId
+export TENCENT_SECRET_KEY=你的SecretKey
+export REDIS_HOST=你的Redis主机
+export REDIS_PORT=你的Redis端口
+```
+
+### 7.2 配置文件
+使用环境变量覆盖配置文件中的敏感信息。
diff --git a/demo/pom.xml b/demo/pom.xml
index 3296caf..ca48f85 100644
--- a/demo/pom.xml
+++ b/demo/pom.xml
@@ -125,6 +125,21 @@
spring-boot-starter-webflux
+
+
+ com.tencentcloudapi
+ tencentcloud-sdk-java
+ 3.1.880
+
+
+
+
+
org.springframework.boot
spring-boot-devtools
diff --git a/demo/src/main/java/com/example/demo/config/TencentCloudConfig.java b/demo/src/main/java/com/example/demo/config/TencentCloudConfig.java
new file mode 100644
index 0000000..1fa93e4
--- /dev/null
+++ b/demo/src/main/java/com/example/demo/config/TencentCloudConfig.java
@@ -0,0 +1,109 @@
+package com.example.demo.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 腾讯云配置类
+ */
+@Configuration
+@ConfigurationProperties(prefix = "tencent.cloud")
+public class TencentCloudConfig {
+
+ /**
+ * 腾讯云SecretId
+ */
+ private String secretId;
+
+ /**
+ * 腾讯云SecretKey
+ */
+ private String secretKey;
+
+ /**
+ * 邮件推送服务配置
+ */
+ private SesConfig ses = new SesConfig();
+
+ /**
+ * 邮件推送服务配置
+ */
+ public static class SesConfig {
+ /**
+ * 邮件服务地域
+ */
+ private String region = "ap-beijing";
+
+ /**
+ * 发件人邮箱
+ */
+ private String fromEmail;
+
+ /**
+ * 发件人名称
+ */
+ private String fromName;
+
+ /**
+ * 验证码邮件模板ID
+ */
+ private String templateId;
+
+ public String getRegion() {
+ return region;
+ }
+
+ public void setRegion(String region) {
+ this.region = region;
+ }
+
+ public String getFromEmail() {
+ return fromEmail;
+ }
+
+ public void setFromEmail(String fromEmail) {
+ this.fromEmail = fromEmail;
+ }
+
+ public String getFromName() {
+ return fromName;
+ }
+
+ public void setFromName(String fromName) {
+ this.fromName = fromName;
+ }
+
+ public String getTemplateId() {
+ return templateId;
+ }
+
+ public void setTemplateId(String templateId) {
+ this.templateId = templateId;
+ }
+ }
+
+ public String getSecretId() {
+ return secretId;
+ }
+
+ public void setSecretId(String secretId) {
+ this.secretId = secretId;
+ }
+
+ public String getSecretKey() {
+ return secretKey;
+ }
+
+ public void setSecretKey(String secretKey) {
+ this.secretKey = secretKey;
+ }
+
+
+ public SesConfig getSes() {
+ return ses;
+ }
+
+ public void setSes(SesConfig ses) {
+ this.ses = ses;
+ }
+}
diff --git a/demo/src/main/java/com/example/demo/controller/AuthApiController.java b/demo/src/main/java/com/example/demo/controller/AuthApiController.java
index 5b69273..b18f5a2 100644
--- a/demo/src/main/java/com/example/demo/controller/AuthApiController.java
+++ b/demo/src/main/java/com/example/demo/controller/AuthApiController.java
@@ -2,6 +2,7 @@ package com.example.demo.controller;
import com.example.demo.model.User;
import com.example.demo.service.UserService;
+import com.example.demo.service.VerificationCodeService;
import com.example.demo.util.JwtUtils;
import jakarta.validation.Valid;
import org.slf4j.Logger;
@@ -11,14 +12,11 @@ import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.context.SecurityContext;
-import org.springframework.security.core.context.SecurityContextHolder;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
@RestController
@@ -36,6 +34,9 @@ public class AuthApiController {
@Autowired
private JwtUtils jwtUtils;
+ @Autowired
+ private VerificationCodeService verificationCodeService;
+
/**
* 用户登录
*/
@@ -81,6 +82,61 @@ public class AuthApiController {
}
}
+ /**
+ * 验证码登录(邮箱)
+ */
+ @PostMapping("/login/email")
+ public ResponseEntity