黑马点评1——短信篇(基于session)

 🌈hello,你好鸭,我是Ethan,一名不断学习的码农,很高兴你能来阅读。

✔️目前博客主要更新Java系列、项目案例、计算机必学四件套等。
🏃人生之义,在于追求,不在成败,勤通大道。加油呀!

🔥个人主页:Ethan Yankang
🔥专栏:黑马点评||Java项目

🔥本篇概览:讲解基于session的短信登录。Threadlocal的使用。双拦截器的使用。数据脱敏的技巧等。

目录

            1、短信登录——基于session

1.1、导入黑马点评项目

1.1.1 、导入SQL

1.1.2、有关当前模型

nginx总结:

1.1.3、导入后端项目

1.1.4、导入前端工程

1.1.5 运行前端项目

1.2 、基于Session实现登录流程

知识补充:session

1.3 、实现发送短信验证码功能

❖ 代码——发送验证码

❖ 代码——登录

1.4、实现登录拦截功能

温馨小贴士:tomcat的运行原理

温馨小贴士:关于threadlocal

❖ 代码——拦截器

❖ 代码——让拦截器生效

1.5、用户信息脱敏

❖代码——将user对象换成UserDTO

1.6、session共享问题——用redis的原因


1、短信登录——基于session

1.1、导入黑马点评项目

1.1.1 、导入SQL

1.1.2、有关当前模型

手机或者app端发起请求,请求我们的nginx服务器,nginx基于七层模型走的是HTTP协议,可以实现基于Lua直接绕开tomcat访问redis,也可以作为静态资源服务器,轻松扛下上万并发, 负载均衡到下游tomcat服务器,打散流量,我们都知道一台4核8G的tomcat,在优化和处理简单业务的加持下,大不了就处理1000左右的并发, 经过nginx的负载均衡分流后,利用集群支撑起整个项目,同时nginx在部署了前端项目后,更是可以做到动静分离,进一步降低tomcat服务的压力,这些功能都得靠nginx起作用,所以nginx(面试准备)是整个项目中重要的一环。

nginx总结:

动静分离

静态部署

负载均衡

在tomcat支撑起并发流量后,我们如果让tomcat直接去访问Mysql,根据经验Mysql企业级服务器只要上点并发,一般是16或32 核心cpu,32 或64G内存,像企业级mysql加上固态硬盘能够支撑的并发,大概就是4000起~7000左右,上万并发, 瞬间就会让Mysql服务器的cpu,硬盘全部打满,容易崩溃,所以我们在高并发场景下,会选择使用mysql集群(面试准备),同时为了进一步降低Mysql的压力,同时增加访问的性能,我们也会加入Redis,同时使用Redis集群(面试准备)使得Redis对外提供更好的服务。

1.1.3、导入后端项目

在资料中提供了一个项目源码:

1.1.4、导入前端工程

1.1.5 运行前端项目

1.2 、基于Session实现登录流程

知识补充:session

在 Web 开发中,Session 指的是服务器为了保存用户在多次请求之间的状态信息而创建的一种机制。当用户访问网站时,服务器会为该用户创建一个唯一的 Session 对象,用于存储用户相关的特定数据,如登录状态、用户偏好等。在同一次会话(会话通常指从用户打开浏览器开始访问某个网站到关闭浏览器的整个过程。)期间,用户与服务器之间的交互可以通过这个 Session 来维护相关状态和数据,使得服务器能够识别是同一个用户在进行操作,从而实现个性化的服务和交互。它通常基于 Cookie 或其他机制在客户端和服务器之间进行关联和传递。

发送验证码:

用户在提交手机号后,会校验手机号是否合法,如果不合法,则要求用户重新输入手机号

如果手机号合法,后台此时生成对应的验证码,同时将验证码进行保存,然后再通过短信的方式将验证码发送给用户(实际上必要的知识验证码,而非短信)。

短信验证码登录、注册:

用户将验证码和手机号进行输入,后台从session中拿到当前验证码,然后和用户输入的验证码进行校验。

如果不一致,则无法通过校验。

如果一致,则后台根据手机号查询用户,如果用户不存在,则为用户创建账号信息,保存到数据库,无论是否存在,都会将用户信息保存到session中,方便后续获得当前登录信息

校验登录状态:

用户在请求时候,会从cookie中携带着JsessionId到后台,后台通过JsessionId从session中拿到用户信息,如果没有session信息,则进行拦截如果有session信息,则将用户信息保存到threadLocal中,并且放行

1.3 、实现发送短信验证码功能

页面流程

具体代码如下

贴心小提示:

具体逻辑上文已经分析,我们仅仅只需要按照提示的逻辑写出代码即可。

  • 代码——发送验证码

 @Overridepublic Result sendCode(String phone, HttpSession session) {// 1.校验手机号if (RegexUtils.isPhoneInvalid(phone)) {// 2.如果不符合,返回错误信息return Result.fail("手机号格式错误!");}// 3.符合,生成验证码String code = RandomUtil.randomNumbers(6);
​// 4.保存验证码到 sessionsession.setAttribute("code",code);// 5.发送验证码log.debug("发送短信验证码成功,验证码:{}", code);// 返回okreturn Result.ok();}
  • 代码——登录

  @Overridepublic Result login(LoginFormDTO loginForm, HttpSession session) {// 1.校验手机号String phone = loginForm.getPhone();if (RegexUtils.isPhoneInvalid(phone)) {// 2.如果不符合,返回错误信息return Result.fail("手机号格式错误!");}// 3.校验验证码Object cacheCode = session.getAttribute("code");String code = loginForm.getCode();if(cacheCode == null || !cacheCode.toString().equals(code)){//3.不一致,报错return Result.fail("验证码错误");}//一致,根据手机号查询用户User user = query().eq("phone", phone).one();
​//5.判断用户是否存在if(user == null){//不存在,则创建user =  createUserWithPhone(phone);}//7.保存用户信息到session中session.setAttribute("user",user);
​return Result.ok();}

1.4、实现登录拦截功能

温馨小贴士:tomcat的运行原理

当用户发起请求时,会访问我们向tomcat注册的端口,任何程序想要运行,都需要有一个线程对当前端口号进行监听,tomcat也不例外,当监听线程知道用户想要和tomcat连接连接时,那会由监听线程创建socket连接,socket都是成对出现的,用户通过socket像互相传递数据,当tomcat端的socket接受到数据后,此时监听线程会从tomcat的线程池中取出一个线程执行用户请求,在我们的服务部署到tomcat后,线程会找到用户想要访问的工程,然后用这个线程转发到工程中的controller,service,dao中,并且访问对应的DB,在用户执行完请求后,再统一返回,再找到tomcat端的socket,再将数据写回到用户端的socket,完成请求和响应

通过以上讲解,我们可以得知 每个用户其实对应都是去找tomcat线程池中的一个线程来完成工作的, 使用完成后再进行回收,既然每个请求都是独立的,所以在每个用户去访问我们的工程时,我们可以使用threadlocal来做到线程隔离,每个线程操作自己的一份数据

温馨小贴士:关于threadlocal

如果小伙伴们看过threadLocal的源码,你会发现在threadLocal中,无论是他的put方法和他的get方法, 都是先从获得当前用户的线程,然后从线程中取出线程的成员变量map,只要线程不一样,map就不一样,所以可以通过这种方式来做到线程隔离

有关Threadlocal详情帖子请点击这里

代码——拦截器

public class LoginInterceptor implements HandlerInterceptor {
​@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//1.获取sessionHttpSession session = request.getSession();//2.获取session中的用户Object user = session.getAttribute("user");//3.判断用户是否存在if(user == null){//4.不存在,拦截,返回401状态码response.setStatus(401);return false;}//5.存在,保存用户信息到ThreadlocalUserHolder.saveUser((User)user);//6.放行return true;}
}

代码——让拦截器生效

@Configuration
public class MvcConfig implements WebMvcConfigurer {
​@Resourceprivate StringRedisTemplate stringRedisTemplate;
​@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 登录拦截器registry.addInterceptor(new LoginInterceptor()).excludePathPatterns("/shop/**","/voucher/**","/shop-type/**","/upload/**","/blog/hot","/user/code","/user/login").order(1);// token刷新的拦截器registry.addInterceptor(new RefreshTokenInterceptor(stringRedisTemplate)).addPathPatterns("/**").order(0);}
}

1.5、用户信息脱敏

我们通过浏览器观察到此时用户的全部信息都在,这样极为不靠谱,所以我们应当在返回用户信息之前,将用户的敏感信息进行隐藏,采用的核心思路就是书写一个UserDto对象,这个UserDto对象就没有敏感信息了,我们在返回前,将有用户敏感信息的User对象转化成没有敏感信息的UserDto对象,那么就能够避免这个尴尬的问题了

在登录方法处修改

//7.保存用户信息到session中
session.setAttribute("user", BeanUtils.copyProperties(user,UserDTO.class));

在拦截器处:

//5.存在,保存用户信息到Threadlocal
UserHolder.saveUser((UserDTO) user);

在UserHolder处:

代码——将user对象换成UserDTO

public class UserHolder {private static final ThreadLocal<UserDTO> tl = new ThreadLocal<>();
​public static void saveUser(UserDTO user){tl.set(user);}
​public static UserDTO getUser(){return tl.get();}
​public static void removeUser(){tl.remove();}
}

1.6、session共享问题——引出用redis的原因

核心思路分析:

每个tomcat中都有一份属于自己的session,假设用户第一次访问第一台tomcat,并且把自己的信息存放到第一台服务器的session中,但是第二次这个用户访问到了第二台tomcat,那么在第二台服务器上,肯定没有第一台服务器存放的session,所以此时整个登录拦截功能就会出现问题,我们能如何解决这个问题呢?早期的方案是session拷贝,就是说虽然每个tomcat上都有不同的session,但是每当任意一台服务器的session修改时,都会同步给其他的Tomcat服务器的session,这样的话,就可以实现session的共享了

但是这种方案具有两个大问题

1、每台服务器中都有完整的一份session数据,服务器压力过大。

2、session拷贝数据时,可能会出现延迟

所以咱们后来采用的方案都是基于redis来完成,我们把session换成redis,redis数据本身就是共享的,就可以避免session共享的问题了

📣非常感谢你阅读到这里,如果这篇文章对你有帮助,希望能留下你的点赞👍 关注❤ 分享👥 留言💬thanks!!!
📚愿大家都能学有所得,功不唐捐!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/14343.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何使用多种算法解决LeetCode第135题——分发糖果问题

❤️❤️❤️ 欢迎来到我的博客。希望您能在这里找到既有价值又有趣的内容&#xff0c;和我一起探索、学习和成长。欢迎评论区畅所欲言、享受知识的乐趣&#xff01; 推荐&#xff1a;数据分析螺丝钉的首页 格物致知 终身学习 期待您的关注 导航&#xff1a; LeetCode解锁100…

Ubuntu中 petalinux 安装 移植linux --tftp/tftp-hpa服务的方法

Xilinx 文档 PetaLinux 指南&#xff1a;如何创建 PetaLinux 环境 &#xff08;2019.1&#xff09; PetaLinux工具参考指南 PetaLinux安装详解(Xilinx , linux, zynq, zynqMP) petalinux 2020.1安装教程 一、PetaLinux工具和库安装 PetaLinux 工具要求主机系统 /bin/sh 为“b…

笔记 | 《css权威指南》

网络安全色 URL text-indent line-height & vertical-align 字体 font-weight 400 normal 700 bold background-attachment

【调试笔记-20240516-Windows-使用VS2019编译edk2(上)】

调试笔记-系列文章目录 调试笔记-20240516-Windows-使用VS2019编译edk2&#xff08;上&#xff09; 文章目录 调试笔记-系列文章目录调试笔记-20240516-Windows-使用VS2019编译edk2&#xff08;上&#xff09; 前言一、安装开发工具1. 安装 VS20192. 安装 Python 3.103. 安装 …

pdf加水印怎么加?3种添加水印方法分享

pdf加水印怎么加&#xff1f;PDF加水印不仅是为了保护文档内容&#xff0c;确保信息的安全性和完整性&#xff0c;更是一种有效的版权保护措施。通过添加水印&#xff0c;您可以在文档中嵌入公司名称、日期、编号等信息&#xff0c;以明确文档的归属权和使用限制。此外&#xf…

小而美:两步完成从源码到应用的极简交付

作者&#xff1a;花三&#xff08;王俊&#xff09; Serverless 应用引擎 SAE 是阿里云推出的一款零代码改造、极简易用、自适应弹性的容器化应用托管平台&#xff0c;面市以来为几万家企业客户提供服务&#xff0c;运行稳定&#xff0c;广受好评。 SAE 的出现解决了众多企业…

运行时异常和编译时异常的区别

Java中的异常被分为两大类&#xff1a;编译时异常和运行时异常。 都是RuntimeException类及其子类异常&#xff0c;如NullPointerException、IndexOutOfBoundsException。这些异常是不检查异常&#xff0c;运行时异常的特点是Java编译器不会检查它&#xff0c;程序中可以选择捕…

纯代码如何实现WordPress搜索包含评论内容?

WordPress自带的搜索默认情况下是不包含评论内容的&#xff0c;不过有些WordPress网站评论内容比较多&#xff0c;而且也比较有用&#xff0c;所以想要让用户在搜索时也能够同时搜索到评论内容&#xff0c;那么应该怎么做呢&#xff1f; 网络上很多教程都是推荐安装SearchWP插…

Spring Web MVC介绍及详细教程

目录 1.什么是Spring Web MVC&#xff1f; 1.1 MVC定义 1.2 Spring MVC与MVC关系 2.为什么要学习Spring MVC 3.项目创建 4.Spring MVC连接 4.1 RequestMapping 4.2 PostMapping和GetMapping 5.Spring MVC参数获取 5.1 获取单个参数 5.2 获取多个参数 5.3 获取普通对…

通用代码生成器应用场景一,项目前期

通用代码生成器是一种自动化编程软件&#xff0c;是一种先进的编译系统。它具有表级抽象。把系统抽象为域对象&#xff0c;枚举&#xff0c;弹性登录模块&#xff0c;复杂版面和图形报表。使用通用代码生成器完成项目前期&#xff0c;比直接使用对应的高级语言快的多&#xff0…

element Notification 消息过多需要折叠

Notification 消息过多太长 希望能折叠 如图下效果 element-plus 可以将dom 插入到具体的元素 结合css :nth-child 来控制样式达到效果 element dom 只能插入到body中 所以无法使用:nth-child 1.Notification需要消息提示时设置class let eleNum 0 // 弹窗的序号 function…

vue+canvas实现逐字手写效果

在pc端进行逐字手写的功能。用户可以在一个 inputCanvas 上书写单个字&#xff0c;然后在特定时间后将这个字添加到 outputCanvas 上&#xff0c;形成一个逐字的手写效果。用户还可以保存整幅图像或者撤销上一个添加的字。 <template><div class"container"…

小红书-社区搜索部 (NLP、CV算法实习生) 一面面经

&#x1f604; 整个流程按如下问题展开&#xff0c;用时60min左右面试官人挺好&#xff0c;前半部分问问题&#xff0c;后半部分coding一道题。 各位有什么问题可以直接评论区留言&#xff0c;24小时内必回信息&#xff0c;放心~ 文章目录 1、自我介绍2、介绍下项目&#xff…

淄博公司商标驳回复审条件及流程

商标是人工审查的&#xff0c;所以不同的人会有不同的想法和意见&#xff0c;导致同一案件的审查结果不同。特别是商标审查周期缩短到5个月&#xff0c;全国平均每个工作日有1万多个商标提交申请&#xff0c;而全国只有一个商标审查单位——国家商标局提交申请。这种情况下&…

Java版工程行业管理系统-提升工程项目的综合管理能力

工程项目管理涉及众多环节和角色&#xff0c;如何实现高效协同和信息共享是关键。本文将介绍一个采用先进技术框架的Java版工程项目管理系统&#xff0c;该系统支持前后端分离&#xff0c;功能全面&#xff0c;可满足不同角色的需求。从项目进度图表到施工地图&#xff0c;再到…

C++_vector操作使用

文章目录 &#x1f680;1.1 vector介绍&#x1f680;1.2 vector的初始化&#x1f680;1.3 vector的常用内置函数&#x1f680;1.4 vector的遍历 &#x1f680;1.1 vector介绍 vector是表示可变大小数组的序列容器。就像数组一样&#xff0c;vector也采用的连续存储空间来存储元…

MySQL主从复制(docker搭建)

文章目录 1.MySQL主从复制配置1.主服务器配置1.拉取mysql5.7的镜像2.启动一个主mysql&#xff0c;进行端口映射和目录挂载3.进入/mysql5.7/mysql-master/conf中创建my.cnf并写入主mysql配置1.进入目录2.执行命令写入配置 4.重启mysql容器&#xff0c;使配置生效5.进入主mysql&a…

2024年电工杯高校数学建模竞赛(B题) 建模解析| 大学生平衡膳食食谱的优化设计 |小鹿学长带队指引全代码文章与思路

我是鹿鹿学长&#xff0c;就读于上海交通大学&#xff0c;截至目前已经帮200人完成了建模与思路的构建的处理了&#xff5e; 本篇文章是鹿鹿学长经过深度思考&#xff0c;独辟蹊径&#xff0c;实现综合建模。独创复杂系统视角&#xff0c;帮助你解决电工杯的难关呀。 本题&…

面试八股之MySQL篇5——主从同步原理篇

&#x1f308;hello&#xff0c;你好鸭&#xff0c;我是Ethan&#xff0c;一名不断学习的码农&#xff0c;很高兴你能来阅读。 ✔️目前博客主要更新Java系列、项目案例、计算机必学四件套等。 &#x1f3c3;人生之义&#xff0c;在于追求&#xff0c;不在成败&#xff0c;勤通…

IP地址的风险画像及其应用

在现代互联网环境中&#xff0c;IP地址不仅是设备在网络中的唯一标识符&#xff0c;还是分析网络安全和风险管理的重要工具。IP地址的风险画像通过分析IP地址的行为和相关数据&#xff0c;揭示潜在的安全威胁&#xff0c;为企业和组织提供有效的风险管理方案。本文将探讨IP地址…