• 瑞吉外卖 —— 7、手机验证码登录


    目录

    1、短信发送

    1.1、短信发送 

    1.2、短信验证码登录

    1.2.1、分析

            1.2.1.1、需求分析

            1.2.1.2、数据模型

            1.2.1.3、交互过程

            1.2.1.4、准备工作

    1.2.2、代码

            1.2.2.1、修改 LoginCheckFilter

            1.2.2.2、修改 SMSUtils 工具类

            1.2.2.3、发送短信验证码

            1.2.2.4、校验验证码


    关于短信发送可以看:使用阿里云实现短信发送服务(测试版)_QinYanan.的博客-CSDN博客 

    1、短信发送

    1.1、短信发送 

    短信使用阿里云的短信功能,这里由于是个人,难以申请签名,只好先学着,使用测试短信。

    官方文档:Java SDK - 短信服务 - 阿里云 

    具体可以看官方视频:Java SDK - 短信服务 - 阿里云

    首先引入 maven 依赖

    1. <dependency>
    2. <groupId>com.aliyungroupId>
    3. <artifactId>aliyun-java-sdk-coreartifactId>
    4. <version>4.5.16version>
    5. dependency>
    6. <dependency>
    7. <groupId>com.aliyungroupId>
    8. <artifactId>aliyun-java-sdk-dysmsapiartifactId>
    9. <version>2.1.0version>
    10. dependency>

    然后导入资料中的 SMSUtils 工具类

    1.2、短信验证码登录

    1.2.1、分析

    1.2.1.1、需求分析

    1.2.1.2、数据模型

    通过手机验证码登录时,涉及的表为user表,即用户表。结构如下:

    1.2.1.3、交互过程

    发送验证码请求:

    登录请求:

    1.2.1.4、准备工作

    1.2.2、代码

    1.2.2.1、修改 LoginCheckFilter

    添加判断移动端登录状态的语句

    1. // 移动端
    2. if(request.getSession().getAttribute("user") != null){
    3. //Long id = Thread.currentThread().getId();
    4. //log.info("线程id为{}", id);
    5. //log.info("用户已登录,放行,用户id为{}", request.getSession().getAttribute("user"));
    6. Long userId = (Long) request.getSession().getAttribute("user");
    7. BaseContext.setCurrentId(userId);
    8. filterChain.doFilter(request, response);
    9. return;
    10. }

    1.2.2.2、修改 SMSUtils 工具类

    1. package com.itheima.reggie.utils;
    2. import com.aliyuncs.DefaultAcsClient;
    3. import com.aliyuncs.IAcsClient;
    4. import com.aliyuncs.exceptions.ClientException;
    5. import com.aliyuncs.exceptions.ServerException;
    6. import com.aliyuncs.profile.DefaultProfile;
    7. import com.google.gson.Gson;
    8. import java.util.*;
    9. import com.aliyuncs.dysmsapi.model.v20170525.*;
    10. /*
    11. pom.xml
    12. com.aliyun
    13. aliyun-java-sdk-core
    14. 4.6.0
    15. com.aliyun
    16. aliyun-java-sdk-dysmsapi
    17. 2.2.1
    18. */
    19. public class SMSUtils {
    20. public static void sendMessage(String phone, String code) {
    21. DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", "", "");
    22. /** use STS Token
    23. DefaultProfile profile = DefaultProfile.getProfile(
    24. "", // The region ID
    25. "", // The AccessKey ID of the RAM account
    26. "", // The AccessKey Secret of the RAM account
    27. ""); // STS Token
    28. **/
    29. IAcsClient client = new DefaultAcsClient(profile);
    30. SendSmsRequest request = new SendSmsRequest();
    31. request.setSignName("阿里云短信测试");
    32. request.setTemplateCode("SMS_154950909");
    33. request.setPhoneNumbers(phone);
    34. request.setTemplateParam("{\"code\":\"" + code + "\"}");
    35. try {
    36. SendSmsResponse response = client.getAcsResponse(request);
    37. System.out.println(new Gson().toJson(response));
    38. } catch (ServerException e) {
    39. e.printStackTrace();
    40. } catch (ClientException e) {
    41. System.out.println("ErrCode:" + e.getErrCode());
    42. System.out.println("ErrMsg:" + e.getErrMsg());
    43. System.out.println("RequestId:" + e.getRequestId());
    44. }
    45. }
    46. }

    1.2.2.3、发送短信验证码

    在 UserController 中添加方法

    1. @RestController
    2. @RequestMapping("/user")
    3. @Slf4j
    4. public class UserController {
    5. @Autowired
    6. private UserService userService;
    7. /**
    8. * 发送手机验证码
    9. * @param user
    10. * @return
    11. */
    12. @PostMapping("/sendMsg")
    13. public R sendMsg(@RequestBody User user, HttpSession session) throws ExecutionException, InterruptedException {
    14. // 获取手机号
    15. String phone = user.getPhone();
    16. if(StringUtils.isNotEmpty(phone)) {
    17. // 生成随机的4为验证码
    18. String code = ValidateCodeUtils.generateValidateCode(4).toString();
    19. log.info("code={}", code);
    20. // 调用阿里云提供的短信服务API完成发送短信
    21. SMSUtils.sendMessage(phone, code);
    22. // 将验证码存储到Session中
    23. session.setAttribute(phone, code);
    24. return R.success("手机验证码发送成功");
    25. }
    26. return R.error("短信发送失败");
    27. }
    28. }

    1.2.2.4、校验验证码

    ① 前端页面发送请求时没有携带验证码参数,需要修改前端页面

    1. this.loading = true
    2. // const res = await loginApi({phone:this.form.phone})
    3. const res = await loginApi(this.form)
    4. this.loading = false

    ② 在 UserController 中添加方法

    1. /**
    2. * 移动端用户登录
    3. * @param map
    4. * @param session
    5. * @return
    6. */
    7. @PostMapping("/login")
    8. public R login(@RequestBody Map map, HttpSession session){
    9. // 获取手机号、验证码
    10. String phone = map.get("phone").toString();
    11. String code = map.get("code").toString();
    12. // 从session获取保存的验证码
    13. Object codeInSession = session.getAttribute(phone);
    14. // 验证码比对
    15. if(codeInSession != null && codeInSession.equals(code)){
    16. // 比对成功,登录成功
    17. // 判断当前手机号对应的用户是否为新用户,若是则自动完成注册
    18. LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
    19. queryWrapper.eq(User::getPhone, phone);
    20. User user = userService.getOne(queryWrapper);
    21. if(user == null){
    22. user = new User();
    23. user.setPhone(phone);
    24. user.setStatus(1);
    25. userService.save(user);
    26. }
    27. session.setAttribute("user", user.getId());
    28. return R.success(user);
    29. }
    30. return R.error("验证码错误,请重新输入");
    31. }

  • 相关阅读:
    2023-09-09青少年软件编程(C语言)等级考试试卷(一级)解析
    电子邮件营销初学者指南(二):如何开始与撰写
    数据结构--线性表回顾
    使用kepware配置opcua服务端,并使用UaExpert作为opc客户端进行连接
    基于web的课程管理系统设计与实现(java+SqlServer)
    基于JAVA+SpringMVC+MYSQL的宠物管理系统
    流程控制语句 循环结构 ---- for循环
    MySQL数据库性能分析与调优实践
    7-2 大盗阿福
    MYSQL——外键约束
  • 原文地址:https://blog.csdn.net/Mr_zhangyj/article/details/126690903