# 7. 程序升级
## 7.1 登录升级
### 7.1.1 图片验证码
* 后端: * 需要一个生成验证码controller,并将生成的验证码随机字符串存放到redis中 * 用户登录时,获得验证码,对验证码进行校验 * 前端: * 编写表单,显示验证码(编写函数修改图片验证码路径),点击时可以切换 * 网关放行
1. 需要一个生成验证码controller,并将生成的验证码随机字符串存放到redis中
2. 用户登录时,获得验证码,对验证码进行校验
@PostMapping("/login")
public BaseResult login(@RequestBody TbUser tbUser) {
//0.1 校验:图片验证码
String key = "login" + tbUser.getUserName();
String redisVerifyCode = stringRedisTemplate.opsForValue().get(key);
stringRedisTemplate.delete(key);
if(redisVerifyCode == null) {
return BaseResult.error("验证码无效");
}
if(! redisVerifyCode.equalsIgnoreCase(tbUser.getImageVerifyCode())) {
return BaseResult.error("验证码错误");
}
//.....
}
3. 编写表单,显示验证码(编写函数修改图片验证码路径),点击时可以切换
4. 网关放行
### 7.1.2 邮箱验证码
* 方案1:使用邮件发送工具类,直接发送邮件。【选择】 * 特点:工具依赖第三方,所以第三方如果比较慢时,我们的程序也会慢 * 方案2:使用MQ作为中间件共享发送的信息,然后使用MQ服务进行邮件的发送。(之前演示) * 特点:使用MQ将第三方解耦,我们的程序不需要依赖第三方的响应时间。
* 后端: * 准备工作:坐标、yml、工具类 * 编写send方法,用于邮件的发送 * 用户登录时,校验邮箱验证码 * 前端: * 提供填写邮箱的位置,并有发送按钮 * 提供填写验证码的位置 * 网关放行
* 后端:
* 准备工作:坐标、yml、工具类
~~~xml <!-- JavaMail 启动器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> ~~~
~~~yml spring: mail: host: smtp.126.com #发送邮件服务器 username: itcast_lt@126.com #账号 password: 1qaz2wsx #密码 default-encoding: UTF-8 #默认编码时 ~~~
* 编写send方法,用于邮件的发送
@Resource
private JavaMailSender javaMailSender;
@PostMapping("/send")
public BaseResult send(@RequestBody TbUser tbUser) {
try {
// 随机验证码
String code = RandomStringUtils.randomNumeric(4);
// 保存到redis
String key = "loginEmail" + tbUser.getUserName();
stringRedisTemplate.opsForValue().set(key, code , 5 , TimeUnit.MINUTES);
// 发送
EmailUtils.sendEmail(javaMailSender, "用户登录", tbUser.getEmail(), "验证码为:" + code);
// 返回
return BaseResult.ok("邮件发送成功");
} catch (Exception e) {
e.printStackTrace();
return BaseResult.error("发送邮件失败");
}
}
* 用户登录时,校验邮箱验证码
//0.2 校验:邮件验证码
String keyEmail = "loginEmail" + tbUser.getUserName();
String redisEmailVerifyCode = stringRedisTemplate.opsForValue().get(keyEmail);
stringRedisTemplate.delete(keyEmail);
if(redisEmailVerifyCode == null) {
return BaseResult.error("email验证码无效");
}
if(! redisEmailVerifyCode.equalsIgnoreCase(tbUser.getEmailVerifyCode())) {
return BaseResult.error("email验证码错误");
}
* 前端:
* 提供填写邮箱的位置,并有发送按钮
async sendEmail() {
let { data: baseResult } = await this.$axios.post(`/user-service/user/send`, this.user)
// 提示
if( baseResult.code == 20000 ) {
this.$message.success( baseResult.message )
} else {
this.$message.error( baseResult.message )
}
}
* 提供填写验证码的位置
* 网关放行
### 7.1.3 作业:短信验证码
## 7.2 学生列表升级
* 注释掉原有内容:
* 编写 asyncData 发送SSR请求
~~~js async asyncData( context ) { // ajax let { data: baseResult } = await context.$axios.get('/classes-service/classes') // 返回结果 return { classesList: baseResult.data } }, ~~~
* 注意:SSR发送请求时,无法获得浏览器端相应的内容(localStorage、sessionStorage、cookie 等)
* 在网关放行
## 7.3 角色列表升级
* 注释已有的
* 编写asyncData发送2次ajax
~~~js async asyncData( context ) { // 发送2次ajax let ajax1 = context.axios.get('/user-service/role') let ajax2 = context.axios.get(`/user-service/perm/parent/0`) let [{data: roleBaseResult}, {data: permBaseResult}] = await Promise.all([ajax1, ajax2]) // 处理数据 return { roleList: roleBaseResult.data, permList: permBaseResult.data } }, ~~~
* 网关配置