[!IMPORTANT]
- 登录功能的完整处理流程是什么?Controller层、Service 层如何具体实现代码?
- 为什么使用 DTO对象接收登录参数?用VO 对象的返回呢?
- JWT 令牌生成的步骤是什么?
- 为什么需要对密码进行 MD5 加密,怎么使用MD5加密?
- 前端请求地址和后端接口路径不同,如何实现映射?这样做的好处是什么?
- 常见的负载均衡策略有哪些?
- Swagger 的核心作用是什么?常用的 Swagger 注解有哪些,Swagger 与 Yapi 的区别是什么?
1.登录功能的完整处理流程是什么?Controller层、Service 层如何具体实现代码?
前端提交用户名密码 →controller层接收前端发送的请求并将用户名和密码封装为EmployeeLoginDTO
→ Controller层调用Service的login方法 → Service层提取username
和password
→ 根据用户名查询数据库(employeeMapper.getByUsername(username)
) → 若未查到数据抛出“账号不存在” → 存在则进行密码校验(MD5加密后比对,错误则抛“密码错误”) → 检查账号状态(若禁用抛“账号被锁定”) → 校验通过返回Employee
对象 → Controller层生成JWT令牌(包含员工ID) → 封装EmployeeLoginVO
(含ID、用户名、姓名、Token) → 返回统一响应 → 前端存储Token用于后续请求鉴权。
controller层代码实现步骤
1.接收请求参数使用 @PostMapping("/login")
声明处理 POST 请求的登录接口。通过 @RequestBody
将前端发送的 JSON 数据解析为 EmployeeLoginDTO
对象(仅含 username
和 password
)。
2.调用 Service 层调用 employeeService.login(employeeLoginDTO)
,传入 DTO 对象,获取数据库中的完整 Employee
实体。
3.生成 JWT 令牌
4.构建 VO 响应对象使用 EmployeeLoginVO.builder()
链式构造响应数据,包含 id
、userName
、name
和 token
字段。
5.返回统一响应格式将 EmployeeLoginVO
封装到 Result.success()
中,返回给前端。
Service 层代码实现步骤
-
提取参数从
EmployeeLoginDTO
中提取username
和password
。 -
查询数据库调用
employeeMapper.getByUsername(username)
,根据用户名查询员工信息。 -
异常校验
(1)用户不存在:若查询结果为
null
,抛出AccountNotFoundException
。(2)密码错误:对用户输入的密码进行 MD5 加密(
DigestUtils.md5DigestAsHex
),与数据库中的密文比对,不一致则抛出PasswordErrorException
。(3)账号锁定:检查
employee.getStatus()
是否为禁用状态(StatusConstant.DISABLE
),若锁定则抛出AccountLockedException
。 -
返回实体对象校验通过后,返回
Employee
实体对象供 Controller 层生成令牌。
2.为什么使用 DTO对象接收登录参数?用VO 对象的返回呢?
用 DTO 接收登录参数原因
用 DTO 接收登录参数,仅含 username
和 password
,避免暴露 Employee
实体敏感信息(如 id
、status
),防止客户端篡改参数注入非法数据,保障系统安全与数据完整。
用 VO 返回数据原因
VO 定制返回前端的数据格式,隐藏 Employee
实体中 password
等敏感信息,还可添加 token
等业务字段,满足前端展示和业务需求。
3.JWT 令牌生成的步骤是什么?什么阶段生成?
在登录校验后,也就是在controller层调用service层登录成功后,开始生成jwt,
-
创建
Claims
对象,存放用户唯一标识(如empId
)。(map集合) -
调用工具类
JwtUtil.createJWT()
,传入密钥、有效期、Claims
。 -
将生成的令牌写入 VO 返回给前端。
4.为什么需要对密码进行 MD5 加密,如何使用MD5进行加密?
为何对密码进行 MD5 加密
MD5 是单向加密算法,无法逆向破解,即便数据库泄露,攻击者也无法直接获取明文密码,提高了密码安全性。
如何使用 MD5 加密
在 Service 层登录逻辑里,借助 DigestUtils.md5DigestAsHex()
加密用户输入的密码。先将密码字符串转为字节数组(password.getBytes()
)以适配不同编码,把加密后的哈希值存到数据库。登录时,重新加密输入密码并和数据库中的值比对。
5.前端请求地址和后端接口路径不同,如何实现映射?这样做的好处是?
通过 Nginx 反向代理配置,通过将前端请求 http://localhost/api/employee/login
→ 代理到 http://localhost:8080/admin/employee/login
- 提高性能:通过缓存减少后端请求压力。
- 负载均衡:将流量分发到多个服务器,避免单点故障。
- 增强安全:隐藏真实后端接口,防止直接暴露。
6.常见的负载均衡策略有哪些?
策略 | 适用场景 |
---|---|
轮询 | 服务器性能均匀的集群环境 |
权重(weight) | 服务器性能差异较大时(如配置不同) |
IP哈希 | 需要会话保持的场景(如购物车) |
最少连接 | 长连接服务(如 WebSocket) |
7.Swagger 的核心作用是什么?常用的 Swagger 注解有哪些?怎么用?Swagger 与 Yapi 的区别是什么?
Swagger 核心作用
可在浏览器直接测试接口功能,还能用注解描述接口参数和返回值。
常用 Swagger 注解及用法
@Api(tags="分类")
:标记控制器功能分类,如 “员工相关接口”。@ApiOperation("接口说明")
:描述接口功能,如 “员工登录”。@ApiModelProperty("字段说明")
:解释模型字段含义,如 “用户名”。
Swagger 使用步骤
添加依赖配置 →Docket→设置静态资源→用注解描述接口→最后通过 doc.html
页面实时测试接口。
Swagger 与 Yapi 区别
Swagger 用于开发阶段,适合后端调试;Yapi 用于设计阶段。