河间市做网站,郑州网站推广哪家效果好,美食介绍网站模板,哈尔滨信息网招聘一、基于session实现登录功能 第一步#xff1a;发送验证码#xff1a; 用户在提交手机号后#xff0c;会校验手机号是否合法#xff1a; 如果不合法#xff0c;则要求用户重新输入手机号如果手机号合法#xff0c;后台此时生成对应的验证码#xff0c;同时将验证码进行…一、基于session实现登录功能 第一步发送验证码 用户在提交手机号后会校验手机号是否合法 如果不合法则要求用户重新输入手机号如果手机号合法后台此时生成对应的验证码同时将验证码进行保存存到session里面然后再通过短信的方式将验证码发送给用户 第二步短信验证码登录、注册 用户输入刚刚获取到的验证码而后台则从session中拿到当前验证码然后和用户输入的验证码进行校验 如果不一致则无法通过校验提示验证码错误如果一致则后台根据手机号查询用户 如果用户不存在则为用户创建账号信息保存到数据库再将用户信息保存到session中如果存在则直接存入到session中取。 无论是否存在都会将用户信息这个用户信息可以创建个UserDTO对象把想要暴露的信息存储到session中去这样就可以减少数据暴露的风险保存到session中方便后续获得当前登录信息。 第三步校验登录状态登录时的逻辑: 用户在请求登录的时候会从cookie中携带者JsessionId到后台后台通过JsessionId从session中拿到用户信息 如果没有session信息则进行拦截无法进行登录。如果有session信息则将用户信息保存到threadLocal中并且放行。 使用拦截器当每个业务都需要进行用户信息的验证时不可能每个业务都写一次登录校验的逻辑这就需要使用到拦截器了拦截器是在所有的业务执行之前执行的。我们把这个登录校验的逻辑写到拦截器里面去这样每次用户无论访问哪个业务都需要经过拦截器然后让拦截器判断是否放行该用户访问业务。 tomcat运行原理 当用户发起请求时会访问我们向tomcat注册的端口 任何程序想要运行都需要有一个线程对当前端口号进行监听tomcat也不例外。 当监听线程知道用户想要和tomcat进行连接时那会由监听线程创建socket连接。 socket都是成对出现的用户通过socket互相传递数据当tomcat端的socket接收到数据后此时监听线程会从tomcat的线程池中取出一个线程执行用户请求。 当我们的服务部署到tomcat后线程会找到用户想要访问的工程然后用这个线程转发到工程中的controllerservicedao中并且访问对应的DB在用户执行完请求后再统一返回再找到tomcat端的socket再将数据写回到用户端的socket完成请求和响应 结论每个用户其实对应都是去找tomcat线程池中的一个线程来完成工作的 使用完成后再进行回收既然每个请求都是独立的所以在每个用户去访问我们的工程时我们可以使用threadlocal来做到线程隔离每个线程操作自己的一份数据Threadlocal的基本使用 在threadLocal中无论是它的put方法和他的get方法 都是先从获得当前用户的线程然后从线程中取出线程的成员变量map只要线程不一样map就不一样所以可以通过这种方式来做到线程隔离。
二、集群的session共享问题使用redis代替
session共享问题其实就是多台tomcat服务器并不共享session存储空间每个tomcat有自己的session当请求切换到不同的tomcat服务时导致数据丢失的问题。
思路分析
每个tomcat中都有一份属于自己的session,假设用户第一次访问第一台tomcat并且把自己的信息存放到第一台服务器的session中但是第二次这个用户访问到了第二台tomcat那么在第二台服务器上肯定没有第一台服务器存放的session所以此时 整个登录拦截功能就会出现问题我们能如何解决这个问题呢 早期的方案是session拷贝就是说虽然每个tomcat上都有不同的session但是每当任意一台服务器的session修改时都会同步给其他的Tomcat服务器的session这样的话就可以实现session的共享了但是这种方案具有两个大问题 1、每台服务器中都有完整的一份session数据·服务器压力过大·。2、session拷贝数据时可能会出现延迟。
解决方法
基于redis来完成我们把session换成redisredis数据本身就是共享的就可以避免session共享的问题了。
第一步设计redis的value的结构
利用redis来存储数据那么到底使用哪种结构呢 如果存入的数据比较简单我们可以考虑使用String或者是使用哈希。 当存入的数据是一个对象时value如果使用String结构时会把java对象序列化成一个json字符串然后存储。使用string结构时会有一些额外的数据存储比如json的格式等等而且每次修改都要修改整个字符串当存入的数据是一个对象时value如果使用哈希则它的value中只会存储数据本身修改可以直接修改单个字段。如果不是特别在意内存其实使用String就可以啦。
第二步redis的key的设计
1、key要具有唯一性2、key要方便携带
第三步设置redis的key的存活时间
就好比你使用百度等其它的软件时你每次登录进去之后在一段时间之内退出来再进去都不需要再重新进行登录只要不是退出登录过了特定的时间之后就需要重新登录了。原因就可以理解为存储你登录信息的数据的key过期了存储在redis的登录数据没了具体设计只要用户还在操作无论在访问哪个服务都需要重新刷新key的存活时间只有当用户不再操作的时候才会计算key的存活时间直到时间过去之后才会销毁key。
整体访问流程
用户去登录时会去校验用户提交的手机号和验证码是否一致如果一致则根据手机号查询用户信息并将用户数据保存到redis并且生成token作为redis的key。 如果用户不存在则新建一个用户然后将新建用户的数据保存到数据库中然后再保存到redis并且生成token作为redis的key 当我们校验用户是否登录时会去携带着token进行访问从redis中取出token对应的value判断是否存在这个数据 如果不存在这个数据则拦截登录如果存在则将其保存到threadLocal中并且放行。