• SpringBoot基于Session实现短信验证码登录


    🎥项目源码地址

    链接: https://pan.baidu.com/s/1LkJDNwV5THPoywbEX6Gpyg

    提取码: gajm

    🍎 1.验证码登录所需要的功能接口

    思路 : 这个我们需要两个接口来实现, 分别是发送验证码和登录功能

    代码 :

    1. /**
    2. * 发送手机验证码
    3. */
    4. @PostMapping("code")
    5. public Result sendCode(@RequestParam("phone") String phone, HttpSession session) {
    6. // TODO 发送短信验证码并保存验证码
    7. return userService.sendCode(phone, session);
    8. }
    9. /**
    10. * 登录功能
    11. * @param loginForm 登录参数,包含手机号、验证码;或者手机号、密码
    12. */
    13. @PostMapping("/login")
    14. public Result login(@RequestBody LoginFormDTO loginForm, HttpSession session){
    15. // TODO 实现登录功能
    16. return userService.login(loginForm, session);
    17. }

    🍊2. 发送验证码业务实现

    思路 : 校验手机号(正则) ➡️ 生成验证码 ➡️ 将验证码保存到Session中 ➡️ 返回OK 

    代码 :

    1. @Override
    2. public Result sendCode(String phone, HttpSession session) {
    3. //1.校验(正则)手机号
    4. if (RegexUtils.isPhoneInvalid(phone)) {
    5. //2.如果不符合, 返回错误信息
    6. return Result.fail("手机号格式错误!");
    7. }
    8. //3.符合, 生成验证码
    9. String code = RandomUtil.randomNumbers(6);
    10. //4.保存验证码到session中
    11. session.setAttribute("code", code);
    12. //5.发送验证码 后期有空调阿里云的api
    13. log.debug("手机号:{} 发送短信验证码成功, 验证码: {}", phone, code);
    14. //6.返回OK
    15. return Result.ok();
    16. }

     🍅3. 登录功能

    思路 : 校验手机号(正则) ➡️ 校验验证码 ➡️  根据手机号查询用户 ➡️  如果不存在就创建用户 ➡️  保存用户信息到Session中

    代码 :

    1. @Override
    2. public Result login(LoginFormDTO loginForm, HttpSession session) {
    3. //1.校验手机号
    4. String phone = loginForm.getPhone();
    5. if (RegexUtils.isPhoneInvalid(phone)) {
    6. //2.如果不符合, 返回错误信息
    7. return Result.fail("手机号格式错误!");
    8. }
    9. Enumeration attributeNames = session.getAttributeNames();
    10. System.out.println(attributeNames);
    11. //3.校验验证码
    12. Object cacheCode = session.getAttribute("code");
    13. String code = loginForm.getCode();
    14. if (cacheCode == null || !cacheCode.toString().equals(code)){
    15. //4.不一致,报错
    16. return Result.fail("验证码错误");
    17. }
    18. //5.一致的话, 根据手机号查询用户
    19. User user = query().eq("phone", phone).one();
    20. //6.判断用户是否存在
    21. if (user == null) {
    22. //不存在, 创建新用户
    23. user = createUserWithPhone(phone);
    24. }
    25. //7.保存用户信息到session中
    26. session.setAttribute("user", user);
    27. return Result.ok();
    28. }

    🍖4. 拦截器

    思路 : 利用SpringMVC的拦截器, 来拦截请求, 首先我们要制定拦截的规则, 最后再设置接口的拦截或放行

    代码1 : 设置拦截规则

    1. public class LoginInterceptor implements HandlerInterceptor {
    2. @Override
    3. //前置拦截
    4. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    5. //1.获取session
    6. HttpSession session = request.getSession();
    7. //2.获取session中的用户
    8. Object user = session.getAttribute("user");
    9. //判断用户是否存在, 如果请求的接口没有被放行, 但是session中是存在用户信息, 该接口也可以被访问到
    10. if (user == null){
    11. //4.不存在, 拦截返回401状态码
    12. response.setStatus(401);
    13. return false;
    14. }
    15. //存在,保存用户信息到ThreadLocal
    16. UserHolder.saveUser((User)user);
    17. //6.放行
    18. return true;
    19. }
    20. @Override
    21. //Controller执行之后拦截
    22. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    23. HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    24. }
    25. @Override
    26. //视图渲染之后
    27. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    28. //移除用户
    29. UserHolder.removeUser();
    30. }
    31. }

    代码2 : 设置要放行的接口

    1. @Configuration
    2. public class MvcConfig implements WebMvcConfigurer {
    3. @Override
    4. public void addInterceptors(InterceptorRegistry registry) {
    5. registry.addInterceptor(new LoginInterceptor())
    6. //要方行的接口,
    7. .excludePathPatterns(
    8. "/user/code",
    9. "/user/login"
    10. );
    11. }
    12. }

    🌐 5.集群Session共享问题

    session共享问题:多台Tomcat并不共享session存储空间,当请求切换到不同tomcat服务时导致数据丢失的问题。 session的替代方案应该满足:

    数据共享

    内存存储 key、

    value结构

     

     

  • 相关阅读:
    服务名无效。 请键入 NET HELPMSG 2185 以获得更多的帮助。
    netty(二)基础 多线程情况下的selector
    字典树 (Trie)
    linux多处理器并发访问共享资源---自旋锁
    爬虫项目(八):自动获取CSDN博客文章质量评分
    自定义类型:结构体、位段、枚举、联合
    Excel练习:双层图表
    java进阶-Netty
    Web3和区块链开发国内外顶级资源大赏
    简约的博客网页制作 大学生个人博客网页设计模板 学生个人网页成品 DIV简单个人网站作品下载 静态HTML CSS个人网页作业源代码
  • 原文地址:https://blog.csdn.net/qq_45481709/article/details/127835152