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

天津百度网站排名优化seo建站教程

天津百度网站排名优化,seo建站教程,家居网站建设素材,广州文化网站模板目录 IDEA集成git 传统session存在的问题 redis方案 业务流程 选用的数据结构 整体访问流程 发送短信验证码 获取校验验证码 配置登录拦截器 拦截器注册配置类 拦截器 用户状态刷新问题 刷新问题解决方案 IDEA集成git 远程仓库采用码云#xff0c;创建好仓库创建好仓库复制仓库的url 在idea中点击出现git选项点击ok 之后右击项目点击remotes 填写url即可集成git 传统session存在的问题  传统的登录认证会采用session进行登录认证将登录的验证码用户信息都存放到session中我们通过session来进行操作数据这有什么问题呢 每个tomcat服务器中都有一份属于自己的session,假设用户第一次访问第一台tomcat并且把自己的信息存放到第一台服务器的session中但是第二次这个用户访问到了第二台tomcat那么在第二台服务器上肯定没有第一台服务器存放的session即session在各个服务器之间是不共通的所以此时整个登录拦截功能就会出现问题而redis数据本身就是共享的就可以避免session共享的问题了 redis方案 业务流程 将验证码存储到redis中将用户数据存储到redis中 选用的数据结构 存储验证码时采用String类型key采用业务代码手机号 存储user数据时采用hashkey采用业务代码随机的tonke hash可以将对象中的每个字段独立存储可以针对单个字段做CRUD并且内存占用更少实际上也可以采用String类型但hash类型消耗内存较少故选用String类型 整体访问流程 当注册完成后用户去登录会去校验用户提交的手机号和验证码是否一致如果一致则根据手机号查询用户信息不存在则新建最后将用户数据保存到redis并且生成token作为redis的key当我们校验用户是否登录时会去携带着token进行访问从redis中取出token对应的value判断是否存在这个数据如果没有则拦截如果存在则将其保存到threadLocal中简化后续业务获取用户信息的代码后续业务需要登录用户的信息只要在threadLocal中取即可无需从redis中取从而增加复杂度最后放行。 redis业务代码常量后续继续补充 public class RedisConstants {//发送验证码业务标识public static final String LOGIN_CODE_KEY login:code:;public static final Long LOGIN_CODE_TTL 2L;//用户登录业务标识public static final String LOGIN_USER_KEY login:token:;public static final Long LOGIN_USER_TTL 30L;} 发送短信验证码 采用日志打印形式将验证码打印在控制台 public Result sendCode(String phone) {//校验手机号if (RegexUtils.isPhoneInvalid(phone)) {return Result.fail(手机号码格式不正确);}//手机号格式正确生成验证码String code RandomUtil.randomNumbers(6);//保存到redisstringRedisTemplate.opsForValue().set(LOGIN_CODE_KEY phone, code, LOGIN_CODE_TTL, TimeUnit.MINUTES);//打印日志log.debug(手机验证码为: code);return Result.ok();} 获取校验验证码 我们需要对用户敏感信息进行筛选只给前端返回必要的用户信息数据需要封装dto对象同时在uuid生成token作为redis取数据的key最后要设置过期时间防止reids内存爆炸设置为30分钟因为session的过期时间也是30分钟 public Result login(LoginFormDTO loginForm) {String phone loginForm.getPhone();String code loginForm.getCode();//校验手机号if (RegexUtils.isPhoneInvalid(phone)) {return Result.fail(手机号码格式不正确);}//从redis取验证码进行比对String cacheCode stringRedisTemplate.opsForValue().get(LOGIN_CODE_KEY phone);if (cacheCode null || !cacheCode.equals(code)) {return Result.fail(验证码错误);}//根据电话号码从数据库查询用户是否存在LambdaQueryWrapperUser queryWrapper new LambdaQueryWrapper();queryWrapper.eq(User::getPhone, phone);User user userMapper.selectOne(queryWrapper);//不存在则创建if (user null) {user createUserWithPhone(phone);}String token UUID.randomUUID().toString(true);//只返回不敏感的信息使用dto进行封装UserDTO userDTO new UserDTO();BeanUtils.copyProperties(user, userDTO);//将dto对象转化为map结构MapString, String userMap new HashMap();userMap.put(id, userDTO.getId().toString());userMap.put(icon, userDTO.getIcon());userMap.put(nickName, userDTO.getNickName()); //业务代码token形成redis中的keyString tokenKey LOGIN_USER_KEY token;stringRedisTemplate.opsForHash().putAll(tokenKey, userMap);stringRedisTemplate.expire(tokenKey, LOGIN_USER_TTL, TimeUnit.MINUTES);return Result.ok(token);} 配置登录拦截器 拦截器注册配置类 Configuration public class MvcConfig implements WebMvcConfigurer {Autowiredprivate StringRedisTemplate stringRedisTemplate;Overridepublic void addInterceptors(InterceptorRegistry registry) {// 登录拦截器registry.addInterceptor(new LoginInterceptor(stringRedisTemplate)).excludePathPatterns(/shop/**,/voucher/**,/shop-type/**,/upload/**,/blog/hot,/user/code,/user/login);} } 拦截器 拦截器需要的stringRedisTemplate对象不能通过Autowired直接注入 因为LoginInterceptor 对象是我们手动创建的不受spring管控不在spring容器中故不能注入spring容器中的bean只能通过在配置类中通过构造方法注入stringRedisTemplate对象 public class LoginInterceptor implements HandlerInterceptor {private StringRedisTemplate stringRedisTemplate;public LoginInterceptor(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)) {response.setStatus(401);return false;}String tokenKey LOGIN_USER_KEY token;MapObject, Object userMap stringRedisTemplate.opsForHash().entries(tokenKey);//3.判断用户是否存在if (userMap.isEmpty()) {//4.不存在拦截返回401状态码response.setStatus(401);return false;}UserDTO userDTO BeanUtil.fillBeanWithMap(userMap, new UserDTO(), false);//5.存在保存用户信息到ThreadlocalUserHolder.saveUser(userDTO);//刷新登录状态stringRedisTemplate.expire(tokenKey,LOGIN_USER_TTL,TimeUnit.MINUTES);//6.放行return true;} } 用户状态刷新问题 那就是登录认证和刷新用户状态绑定在一个拦截器中而需要登录认证的路径并不是全部路径如果用户不访问需要登录认证的路径那就刷新不了用户状态即30分钟之后登录就会退出这明显不符合我们的常识 刷新问题解决方案 我们可以再加一个拦截器形成一个拦截器链第一个拦截器对所有路径进行拦截而它的功能就是刷新登录状态登录认证则由第二个拦截器完成 刷新状态拦截器 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 LOGIN_USER_KEY token;MapObject, Object userMap stringRedisTemplate.opsForHash().entries(key);// 3.判断用户是否存在if (userMap.isEmpty()) {return true;}// 5.将查询到的hash数据转为UserDTOUserDTO userDTO BeanUtil.fillBeanWithMap(userMap, new UserDTO(), false);// 6.存在保存用户信息到 ThreadLocalUserHolder.saveUser(userDTO);// 7.刷新token有效期stringRedisTemplate.expire(key, LOGIN_USER_TTL, TimeUnit.MINUTES);// 8.放行return true;}Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 移除用户UserHolder.removeUser();} 登录认证拦截器 public class LoginInterceptor implements HandlerInterceptor {Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 1.判断是否需要拦截ThreadLocal中是否有用户if (UserHolder.getUser() null) {// 没有需要拦截设置状态码response.setStatus(401);// 拦截return false;}// 有用户则放行return true;} } 为了保证拦截器的执行先后顺序配置类需设置order的大小设定拦截器执行的先后的顺序如若不设置就按照注册顺序的先后来执行 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);} }
http://www.dnsts.com.cn/news/10142.html

相关文章:

  • 网站ui设计标准电子商务网站规划与...
  • 工艺礼品东莞网站建设爱网是什么网站
  • 网站欣赏网站现代装修风格2022年
  • 专门做产品排名的网站网站信息填写要求
  • 网站想举报怎么做获客平台有哪些
  • 网站设计优缺点分析医院网站建设投标要求
  • 网站开发流程框架西安优惠电商平台网站
  • 重庆网站优化公司哪家便宜做旅游景区网站
  • 网站建设是怎么挣钱深圳航空公司最新招聘
  • 南宁网站优化排名推广做网站首页应该考虑什么
  • 如何架设网站服务器做的好的旅游网站
  • 简单个人网站欣赏设计素材网站推荐pin
  • 北京网站建设曝光尚词网大连建站系统模板
  • 新企业建网站上海专门做培训的网站
  • 城乡建设部门户网站虚拟主机有哪些
  • 网络公司经营范围网站建设东营建设局网站
  • 做线上网站的风险分析西安网络营销推广咨询
  • php网站美化建设工程公司 网站
  • 胶州网站搭建公司爬虫python入门
  • 建设科技信息+网站建设大连学校网站建设
  • 北京网站设计公司飞沐wordpress 关闭自动保存
  • 帝国cms 网站名称黔西做网站
  • 知名自适应网站建设哪家好吉林高端网站建设
  • 网站开发技术htmlwordpress实现自动重定向
  • 线上推广方式有哪些seo关键词优化推广报价表
  • 杭州专业网站设计化工行业网站设计
  • 教育培训类网站开发wordpress 标签 彩色
  • 小企业网站建设论文商业网站开发岗位需求分析
  • 怎么建好网站番禺网络公司
  • 制作网站的程序潍坊网站制作培训