用户登录流程与信息验证机制
📌 用户登录流程
当用户在前端输入手机号/邮箱和密码后,点击登录按钮,
前端会将输入的数据打包成请求体,并向后端发送POST /api/auth/login请求。
后端接收到请求后,首先会验证账号是否存在,如果用户不存在,则返回**“用户不存在”的错误信息。若账号存在,后端会对输入的密码进行加密比对**,通常使用BCrypt或哈希算法来验证密码是否正确。如果密码错误,后端返回**“密码错误”的提示信息,前端会在页面上显示相应的错误提示。如果密码正确,后端会生成 JWT(JSON Web Token),其中包含用户的身份信息和权限,并将该 token 返回给前端。
前端收到 token 后,会存入本地存储或 Cookie**,并将用户重定向到系统首页或个人中心。后续所有需要身份验证的请求,前端都会在请求头中携带 token,后端通过解析 token 验证用户身份,确保安全访问。
一、登录流程
- 用户输入信息:
- 用户在前端页面输入用户名/手机号和密码,点击“登录”按钮。
- 前端请求发送:
- Vue3通过Axios发送POST请求到后端登录接口(如/api/login),请求体包含加密后的账号密码(如使用RSA加密传输)。
- 后端身份验证:
- Spring Security调用UserDetailsService查询数据库(MySQL),验证用户是否存在。
- 密码校验:使用BCrypt算法比对数据库中的加密密码与用户输入密码是否匹配。
- 生成并返回Token:
- 验证成功后,后端生成JWT Token(包含用户ID、角色、有效期),返回给前端。
- 前端处理Token:
- 前端将Token存储在localStorage或sessionStorage中,并通过Vue Router跳转到首页。
- 动态路由:根据用户角色(管理员、医生、用户)渲染对应的导航菜单。
二、信息验证机制
- 密码安全存储:
- 数据库中的密码字段使用BCrypt加密(Spring Security默认),不可逆存储。
- 示例:password = BCrypt.hashpw(rawPassword, BCrypt.gensalt())。
- 传输加密:
- HTTPS:全程加密传输,防止中间人窃听。
- 敏感字段(如密码)前端使用RSA加密,后端解密后验证。
- Token验证:
- 用户后续请求通过Axios拦截器自动附加Token到请求头:
Js
axios.interceptors.request.use(config => {
config.headers.Authorization = `Bearer ${localStorage.getItem('token')}`;
return config;
});
- 后端通过JWT解析验证Token合法性(签名、有效期),并从Token中提取用户角色和ID。
- 权限控制:
- 前端:通过Vue Router导航守卫拦截非法路由(如普通用户访问医生管理页)。
- 后端:使用@PreAuthorize("hasRole('ADMIN')")注解校验接口权限。
- 防暴力破解:
- 限制同一IP/账号的登录失败次数(如Redis记录失败尝试,5次失败后锁定1小时)。
三、关键安全设计
- SQL注入防护:MyBatis使用#{}占位符,避免拼接SQL。
- XSS攻击防护:前端v-html渲染时过滤,后端用Hutool的HtmlUtil.filter()清洗输入。
- Token安全:设置较短有效期(如2小时),并支持续期(Refresh Token)。
流程图示
用户输入 → 前端加密传输 → 后端验密 → 生成Token → 前端存储 → 权限控制
全程加密 + 无状态Token,兼顾安全性与扩展性。
一、请简述系统从用户登录到展示首页的完整流程
- 用户输入登录信息:用户在Vue3前端页面输入账号(用户名/手机号)和密码,点击“登录”按钮。
- 前端请求发送:Vue3通过Axios发送POST请求到后端接口(如/api/login),请求体包含加密后的账号密码(如使用RSA非对称加密)。
- 后端身份验证:
- SpringBoot3接收请求,Spring Security调用UserDetailsService查询数据库(MySQL)验证用户是否存在及密码(BCrypt加密)是否匹配。
- 若验证成功,生成JWT Token(包含用户ID、角色、有效期),并返回给前端。
- 前端存储Token与路由跳转:
- 前端收到Token后,存入localStorage或sessionStorage,并通过Vue Router跳转至首页。
- 根据用户角色(管理员/医生/用户),动态渲染对应的导航菜单(如管理员显示“轮播图管理”选项)。
- 首页数据加载:
- 前端调用首页接口(如GET /api/home),携带Token请求数据(如轮播图、心理测试统计、公告)。
- 后端通过MyBatis查询数据库,聚合数据(如近一周测试人数、题目分类统计),返回JSON格式结果。
- 前端渲染页面:
- Vue3解析响应数据,通过Element-Plus组件(如<el-table>、<el-carousel>)渲染首页内容。
技术亮点:
- 全链路加密(RSA + HTTPS + JWT)。
- 动态路由权限控制(基于角色渲染菜单)。
- 数据聚合优化(减少多次请求)。
简化版医生出题流程(无需管理员审核)
📌 医生心理测试出题流程
医生登录系统后,在心理测试管理页面,点击新增测试按钮,前端会展示一个表单,医生需要输入测试名称、测试描述、适用人群,然后添加具体的题目。题目通常包括题干、选项、评分规则,医生可以选择单选、多选、填空等不同题型。完成题目编辑后,医生点击提交,前端会将所有测试数据打包成请求体,发送POST /api/tests请求到后端。后端接收到请求后,首先进行数据校验,确保测试名称不为空,题目格式正确。然后,后端会在数据库中创建测试记录,存储测试基本信息,并逐条插入测试题目及选项到题目表和选项表,同时生成测试的唯一 ID。数据库存储完成后,后端返回创建成功的响应,并将测试 ID 返回给前端。前端接收到成功状态后,跳转到测试列表页面,医生可以在列表中查看刚刚创建的心理测试,并进行发布、修改或删除操作。如果系统支持 AI 题目推荐,后端也可以在医生出题时提供智能建议,帮助医生更高效地创建测试。
1. 流程概述
- 医生创建试卷:直接填写试卷信息并添加题目。
- 即时发布:试卷自动对用户可见,无需审核。
- 用户测试:用户完成测试后,结果自动反馈给医生。
2. 具体实现步骤
(1)数据库调整
- 删除状态字段:简化paper表,移除status字段。
sql
CREATETABLEpaper (id INTPRIMARYKEYAUTO_INCREMENT,title VARCHAR(100)NOTNULL,doctor_id INTNOTNULL,-- 关联医生IDcreate_time DATETIME,FOREIGNKEY(doctor_id)REFERENCESuser(id));
创建表格文件(id INT主键自动增量,标题VARCHAR(100)NOTNULL,doctor_id INTNOTNULL,-- 关联医生ID创建时间DATETIME,外键(医生id )引用用户(id ));
(2)前端修改(Vue3)
- 移除审核相关UI:
- 删除“提交审核”按钮,改为“立即发布”按钮。
- 界面直接显示“发布成功”,无需提示等待审核。
vue
<el-buttontype="primary"@click="publishPaper">立即发布</el-button>
- 接口调用:
- 点击按钮后,直接调用POST /api/paper/publish发布试卷。
(3)后端调整(SpringBoot3)
- 接口逻辑:
- 医生创建试卷时,直接插入数据库,无需状态流转。
Java
- 医生创建试卷时,直接插入数据库,无需状态流转。
@PostMapping("/paper/publish")@PreAuthorize("hasRole('DOCTOR')")publicResultpublishPaper(@RequestBodyPaperDTOpaperDTO,@AuthenticationPrincipalUseruser){// 直接保存试卷paperService.createPaper(paperDTO,user.getId());returnResult.success("试卷发布成功");}
@PostMapping(“/paper/publish”)复制代码
@PreAuthorize(“hasRole ('DOCTOR')”)公共结果publishPaper(@RequestBodyPaperDTOpaperDTO ,@AuthenticationPrincipal用户用户){// 直接保存样本paperService .createPaper(paperDTO ,用户.getId());返回结果。success("试卷发布成功");}
- 查询接口:
- 用户端查询试卷时,直接返回所有医生发布的试卷。
java
@GetMapping("/paper/list")publicResultgetPaperList(){List<Paper>papers =paperService.getAllPapers();returnResult.success(papers);}
@GetMapping(“/paper/list”)公共结果获取纸张列表(){列出<论文>papers =paperService .getAllPapers();返回结果。成功(论文);}
- 用户端查询试卷时,直接返回所有医生发布的试卷。
(4)用户测试与反馈
- 流程不变:
- 用户答题后提交,后端计算得分并存储(assessment表)。
- 医生通过接口GET /api/assessment/{paperId}查看自己试卷的测试记录。
3. 技术简化点
- 去状态化:删除审核相关代码(状态枚举、审批日志表)。
- 权限控制:仅校验医生角色,无需校验试卷状态。
- 数据查询优化:用户端直接查询paper表全部数据。
4. 流程图
复制
医生创建试卷 → 保存至数据库 → 用户立即可见 → 用户测试 → 结果反馈医生
全程无审核环节,医生操作即生效。
📌 1. 预约流程(数据流)
用户预约过程:
1️⃣ 用户在前端选择医生、预约日期、时间段,并提交预约表单。
2️⃣ 前端调用后端 API,将预约信息发送到服务器。
3️⃣ 后端接收请求,校验预约时间是否可用,并将数据存入数据库。
4️⃣ 数据库存储预约数据,防止时间冲突。
5️⃣ 后端返回预约结果(成功 or 失败)给前端。
6️⃣ 前端根据后端返回的状态,显示“预约成功”或“预约失败”提示。
7️⃣ 医生端收到预约提醒(可以用 WebSocket 或消息队列通知)。
当用户提交预约申请时,前端会先收集用户选择的医生、预约日期、时间段,然后通过Axios或Fetch API向后端发送POST /api/appointments请求,携带预约信息。后端接收到请求后,首先会校验数据完整性,确保医生ID、用户ID、日期和时间段都有效。接着,后端会查询数据库,检查该医生在指定时间段是否已有预约,如果时间已被占用,则直接返回预约失败的响应,前端会显示“预约失败,时间已被占用”。如果时间可用,后端会创建预约记录,将数据存入数据库,并默认设置预约状态为**“待确认”。数据库完成存储后,后端返回预约成功的响应。前端接收到成功状态后,会显示“预约成功”的提示,并可能跳转至预约详情页面。与此同时,系统可以通过WebSocket、短信或邮件通知医生,有新的预约待处理,医生端可以在管理界面查看预约详情,并进行确认或取消**操作。
我的是B/S架构:
主要区别总结:
特性 | C/S 架构 | B/S 架构 |
客户端 | 专用客户端软件 | Web浏览器 |
客户端功能 | 部分业务逻辑, 数据存储 | 主要负责界面展示 |
更新 | 需要客户端更新 | 服务器端更新即可 |
平台 | 通常有平台限制 | 跨平台 |
安全性 | 客户端安全需要考虑 | 服务器端安全至关重要 |
资源占用 | 客户端资源占用较多 | 客户端资源占用较少 |
优点 | 更强的交互性和用户体验(可以实现更复杂的用户界面)。更高的安全性。可以离线工作 | 开发、维护和部署简单方便。跨平台性好。易于扩展。 |
缺点 | 开发和维护成本较高。部署和更新复杂。平台依赖性强。 | 用户体验可能不如 C/S 架构。 对网络带宽要求较高。 安全性依赖于服务器端 |
问题1:用户前端进行一次操作(例如提交心理测试)最终反馈给用户的过程是什么?
- 用户触发操作:用户在Vue3前端页面点击“提交测试”按钮,触发Axios请求。
- 前端处理:Vue3收集表单数据(如题目ID、选项),通过Axios发送POST请求到后端API(例如/api/assessment/submit)。
- 网络传输:请求经过HTTPS加密传输,携带JWT Token进行身份验证。
- 后端处理:
- SpringBoot3接收请求,通过Spring Security校验Token权限。
- 业务逻辑层计算测试得分(如根据选项匹配心理状态模型)。
- MyBatis操作MySQL,将测试记录写入assessment表,更新用户心理档案。
- 响应返回:后端返回JSON结果(如{ code: 200, data: "提交成功,您的焦虑指数为轻度" })。
- 前端反馈:Vue3根据响应结果,弹窗提示“提交成功”,并跳转到测试报告页展示详细分析。