当前位置: 首页 > news >正文

甜品网站建设策划书辽宁网站建站优化公司

甜品网站建设策划书,辽宁网站建站优化公司,云服务器建设网站,h5建站系统源码2023.12.6 短信登陆如果基于session来实现#xff0c;会存在session共享问题#xff1a;多台Tomcat不能共享session存储空间#xff0c;这会导致当请求切换到不同服务器时出现数据丢失的问题。 早期的解决办法是让session提供一个数据拷贝的功能#xff0c;即让各个Tomcat的…2023.12.6 短信登陆如果基于session来实现会存在session共享问题多台Tomcat不能共享session存储空间这会导致当请求切换到不同服务器时出现数据丢失的问题。 早期的解决办法是让session提供一个数据拷贝的功能即让各个Tomcat的数据实现一个互相的拷贝但是这种方式容易造成内存空间的浪费并且拷贝是需要时间的这段时间内依然存在数据不一致的问题。 于是我们可以基于Redis来完成由于Redis数据本身就是共享的就可以避免session共享的问题了并且redis是基于内存的读写性能高。 发送短信验证码 之前是将验证码保存到session中现在是将验证码保存到redis中此时需要考虑redis采用什么数据结构来保存验证码key需要保证唯一性所以使用用户的手机号作为key由于验证码就是一个六位数的字符串所以value直接采用String保存就好。 该模块的代码如下 public Result sendCode(String phone, HttpSession session) {//1.校验手机号if(RegexUtils.isPhoneInvalid(phone)){//2.不符合则返回错误信息return Result.fail(手机号格式错误);}//3.符合生成验证码String code RandomUtil.randomNumbers(6);//保存验证码到session//session.setAttribute(code,code);//4.保存验证码到redisstringRedisTemplate.opsForValue().set(LOGIN_CODE_KEY phone,code,LOGIN_CODE_TTL, TimeUnit.MINUTES);//设置过期时间定期清理redis中的验证码//5.发送验证码log.debug(发送验证码成功验证码{},code);return Result.ok();} 这里不真的发验证码就模拟一下就好了验证码直接输入到控制台上。 短信验证码登陆和注册模块 这里的redis要存的是用户对象信息于是我们采用HashMap数据结构去存该结构可以将对象的每个字段独立存储方便针对单个字段进行CRUD。 redis的key的选择这里不选择手机号而是采用一个随机token作为key此处的token最终是要返回给前端页面的类似于之前的session id(登陆凭证),所以key填手机号的话不安全并且为了后续能够通过这个token得到用户信息需要将此token返回给客户端。 该模块代码如下 Overridepublic Result login(LoginFormDTO loginForm, HttpSession session) {//1.校验手机号String phone loginForm.getPhone();if(RegexUtils.isPhoneInvalid(phone)){//2.不符合则返回错误信息return Result.fail(手机号格式错误);}//3.从redis获取验证码并校验String cacheCode stringRedisTemplate.opsForValue().get(LOGIN_CODE_KEY phone);String code loginForm.getCode();if(cacheCode null || !cacheCode.equals(code)){//3.验证码不一致报错return Result.fail(验证码错误);}//4.一致根据手机号查询用户User user query().eq(phone, phone).one();//5.判断用户是否存在if(user null){//6.不存在创建新用户并保存user createUserWithPhone(phone);}//7.保存用户信息到redis中//7.1 随机生成token作为登陆令牌String token UUID.randomUUID().toString(true);//7.2 将User对象转为HashMap存储UserDTO userDTO BeanUtil.copyProperties(user, UserDTO.class);MapString, Object userMap BeanUtil.beanToMap(userDTO,new HashMap(),CopyOptions.create().setIgnoreNullValue(true).setFieldValueEditor((fieldName,fieldValue) -fieldValue.toString()));//7.3 存储String tokenKey LOGIN_USER_KEY token;stringRedisTemplate.opsForHash().putAll(tokenKey,userMap);//7.4 设置token有效期stringRedisTemplate.expire(tokenKey,LOGIN_USER_TTL,TimeUnit.MINUTES);// 返回tokenreturn Result.ok(token);}private User createUserWithPhone(String phone) {//1.创建用户User user new User();user.setPhone(phone);user.setNickName(USER_NICK_NAME_PREFIX RandomUtil.randomString(10));//2.保存用户save(user);return user;} 此处有个细节虽然我们设置了token有效期为30分钟但是不管我们登陆后做什么操作token始终都是30分钟后被消除。 而正常情况应该是我们登陆后如果有操作行为token的有效期应该被重置为30分钟。 于是我们可以使用一个拦截器对请求进行拦截每当有请求发生就将token的有效期重置。 拦截器的代码为 public class RefreshTokenInterceptor implements HandlerInterceptor {private StringRedisTemplate stringRedisTemplate;public RefreshTokenInterceptor(StringRedisTemplate stringRedisTemplate) {this.stringRedisTemplate stringRedisTemplate;}Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//1.获取请求头中的tokenString token request.getHeader(authorization);if (StrUtil.isBlank(token)){return true;}//2.基于Token获取redis中的用户String key RedisConstants.LOGIN_USER_KEYtoken;MapObject, Object userMap stringRedisTemplate.opsForHash().entries(RedisConstants.LOGIN_USER_KEY token);//3.判断用户是否存在if(userMap.isEmpty()){return true;}//5.将查询到的Hash数据转为UserDTO对象UserDTO userDTO BeanUtil.fillBeanWithMap(userMap, new UserDTO(), false);//6.保存用户信息到ThreadLocalUserHolder.saveUser(userDTO);//7.刷新token有效期stringRedisTemplate.expire(key,RedisConstants.LOGIN_USER_TTL, TimeUnit.MINUTES);return true;}Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {UserHolder.removeUser();} } 写完拦截器的代码之后还需要在MvcConfig中进行配置 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)).order(0);} } 这里虽然是在第二行配置的刷新有效期拦截器但是它会先进行拦截因为我们order里填的数字是0数字越小优先级越高。 第一行的拦截器是用来进行登陆校验的即如果你访问了除代码中路径以外的路径的话需要判断你有没有登陆那如何判断你有没有登陆呢只需要查看当前ThreadLocal中有无用户信息就知道了该拦截器代码如下 public class LoginInterceptor implements HandlerInterceptor {Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//判断是否需要拦截(即ThreadLocal中是否有用户)if(UserHolder.getUser() null){response.setStatus(401);return false;}return true;}} 拦截器的整体架构图如下
http://www.dnsts.com.cn/news/52650.html

相关文章:

  • p2p理财网站建设旅游网页设计模板免费
  • 怎么做博客网站局域网网页制作
  • 网站开发学生鉴定表云商城之歌
  • 旅游网站建设目的手机软件推荐
  • 做网站的硬件wordpress 腾讯视频插件
  • 企业为什么要建站软件工程造价师
  • flash网站导航怎么做网站开发者morz
  • 威海建设公司网站在线制作非主流流光闪字 急切网
  • 上海网站建设技术指导公司移动互联网软件开发与应用
  • 手机网站模板下载免费网站建设宁波
  • 机械加工外协网站网站标题栏做多大
  • 网站开发长春外贸型网站
  • 郑州网站建设郑州网站建设七彩科技360官方网站
  • 静态网站漏洞用新华做网站名是否侵权
  • 裕华区建设局网站视频生成网址链接
  • 顺的网站建设效果多多淘宝客网站
  • 做营销型网站用什么技术济南手机网站制作
  • 重庆电商网站创新的江苏网站建设
  • 搜狐视频网站联盟怎么做上海市建设工程监理咨询有限公司
  • 个人成立公司怎么做企业网站专业新站整站快速排名公司
  • xampp做网站可以吗大都会app约
  • 兖矿东华建设有限公司网站龙岩网站建设一般多少钱
  • 网站注册商标wordpress wpsyntax
  • 毕业设计做网站起个名字接外包项目的网站
  • 武威市住房和城乡建设局网站石家庄电商网站开发
  • 如何维护给做网站的客户做响应式网站的流程
  • 展示型网站建设流程品牌推广公司排行榜
  • 金融互助平台网站制作莱阳网站开发
  • 怎么设置网站栏目加快百度收录的方法
  • wordpress主题外贸网站wordpress三栏博客主题