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

家电维修做网站生意怎么样局域网视频网站搭建

家电维修做网站生意怎么样,局域网视频网站搭建,品牌网站设计制作一般多少钱,怎样让google收录网站各位小伙伴们大家好#xff0c;欢迎来到这个小扎扎的Redis 6专栏#xff0c;在这个系列专栏中我对B站黑马的Redis教程进行一个总结#xff0c;鉴于 看到就是学到、学到就是赚到 精神#xff0c;这波依然是血赚 ┗|#xff40;O′|┛ #x1f4a1;Redis知识点速览#… 各位小伙伴们大家好欢迎来到这个小扎扎的Redis 6专栏在这个系列专栏中我对B站黑马的Redis教程进行一个总结鉴于 看到就是学到、学到就是赚到 精神这波依然是血赚 ┗|O′|┛ Redis知识点速览 Redis短信登录流程描述 短信验证码的发送 短信验证码的验证 是否登录的验证 源码分析 模拟发送短信验证码 短信验证码的验证 校验是否登录 登录验证优化 Redis短信登录流程描述 短信验证码的发送 用户提交手机号系统验证手机号是否有效毕竟无效手机号会消耗你的短信验证次数还会导致系统的性能下降。如果手机号为无效的话就让用户重新提交手机号如果有效就生成验证码并将该验证码作为value保存到redis中对应的key是手机号之所以这么做的原因是保证key的唯一性如果使用固定字符串作为可以的话会被后面的数据所覆盖。然后在控制台输出验证码模拟发送验证码的过程 短信验证码的验证 用户的手机号接收到验证码后在平台上提交验证码系统从redis中根据手机号读取验证码并进行校验如果验证通过的话就根据用户验证使用的手机号去数据库中进行查询用户信息。如果存在就将查询到的用户信息保存到redis中完成登录如果不存在的话就创建一个新用户并将该用户的信息分别保存到sql数据库和redis中生成随机token作为key、使用hash结构存储user数据作为value并将这个token返回给客户端至此完成登录注册 是否登录的验证 用户访问系统业务逻辑的时候需要校验他是否已经登录如果登录可以访问否则就去登录那么该如何完成是否登录的校验呢这就要了解session的相关知识了每一个session都有一个sessionId信息保存在浏览器的cookie中当用户使用浏览器发送请求的时候会携带上cookie信息此时系统就可以使用cookie中的sessionId获取到session信息并通过session获取到登录时存储的用户信息。如果此时用户在数据库中存在的话就将该用户的信息缓存在ThreadLocal(方便后续验证)中并放行该访问否则就说明发送请求的用户未登录或不合法就要拦截到他的请求前往登录 源码分析 模拟发送短信验证码 UserController定义与前端交互 Resource private IUserService userService;/*** 发送手机验证码*/ PostMapping(code) public Result sendCode(RequestParam(phone) String phone, HttpSession session) {// 发送短信验证码并保存验证码return userService.sendCode(phone, session); }上面使用到了sendCode方法在userService里定义一下接口然后在对应实现类中按照上面的流程重写该方法的业务逻辑代码 Override public Result sendCode(String phone, HttpSession session) {// 校验手机号if (RegexUtils.isPhoneInvalid(phone)) {// 无效手机号返回错误信息return Result.fail(手机号格式有误);}// 有效生成验证码String code RandomUtil.randomNumbers(6);// 保存 (固定前缀手机号) 和验证码到Redis中设置验证码的有效期为2分钟// RedisConstants.LOGIN_CODE_KEY “login:code:”// RedisConstants.LOGIN_CODE_TTL 2LstringRedisTemplate.opsForValue().set(RedisConstants.LOGIN_CODE_KEY phone, code, RedisConstants.LOGIN_CODE_TTL, TimeUnit.MINUTES);// 模拟发送验证码log.debug(验证码{}, code);// 返回return Result.ok(); }手机号格式校验使用到的RegexUtils类中的工具方法 /*** 手机号正则*/ public static final String PHONE_REGEX ^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\\d{8}$;/** * 是否是无效手机格式* param phone 要校验的手机号* return true:符合false不符合*/ public static boolean isPhoneInvalid(String phone){return mismatch(phone, RegexPatterns.PHONE_REGEX); }// 校验是否不符合正则格式 private static boolean mismatch(String str, String regex){if (StrUtil.isBlank(str)) {return true;}return !str.matches(regex); }短信验证码的验证 UserController定义与前端交互其中参数LoginFormDTO 是前端使用手机号验证码登录或者手机号密码登录是传递过来的JSON数据 /*** 登录功能* param loginForm 登录参数包含手机号、验证码或者手机号、密码*/ PostMapping(/login) public Result login(RequestBody LoginFormDTO loginForm, HttpSession session){// 实现登录功能return userService.login(loginForm, session); }上面使用到了login方法在userService里定义一下接口然后在对应实现类中按照上卖弄的流程描述重写该方法的业务逻辑代码 Override public Result login(LoginFormDTO loginForm, HttpSession session) {String phone loginForm.getPhone();// 验证码校验String code loginForm.getCode();String cacheCode stringRedisTemplate.opsForValue().get(RedisConstants.LOGIN_CODE_KEY phone);if (cacheCode null || !code.equals(cacheCode)) {return Result.fail(验证码错误);}// 根据手机号查询用户信息User user query().eq(phone, phone).one();if (user null) {// 不存在就创建一个新用户user createUserWithPhone(phone);}// 保存用户信息到redis中// 生成随机tokenString token UUID.randomUUID().toString(true);// user先转userDTO再转hashMap存储 转HashMap时的第三个参数的意思是忽略null值将值都转换成String类型UserDTO userDTO BeanUtil.copyProperties(user, UserDTO.class);MapString, Object userMap BeanUtil.beanToMap(userDTO, new HashMap(),CopyOptions.create().setIgnoreNullValue(true).setFieldValueEditor((fieldName, fieldValue) - fieldValue.toString()));// RedisConstants.LOGIN_USER_KEY login:token:stringRedisTemplate.opsForHash().putAll(RedisConstants.LOGIN_USER_KEY token, userMap);// 设置失效时间为30分钟// RedisConstants.LOGIN_USER_TTL 30LstringRedisTemplate.expire(RedisConstants.LOGIN_USER_KEY token, RedisConstants.LOGIN_USER_TTL, TimeUnit.MINUTES);// 返回前端tokenreturn Result.ok(token); }private User createUserWithPhone(String phone) {User user new User();user.setPhone(phone);// SystemConstants.USER_NICK_NAME_PREFIX user_user.setNickName(SystemConstants.USER_NICK_NAME_PREFIX RandomUtil.randomString(10));save(user);return user; }保存的时候使用BeanUtil将User转换成UserDTO进行存储UserDTO的结构如下只保存一部分的数据一方面可以不用来回传递用户有关的隐私数据一方面也节省内存提高性能。由于这里的id是数值类型但是stringRedisTemplate存储时需要hash的键值都是String型所以说应该在存储之前将id的值转换成String类型就在上面代码块的24~27行完成了这个操作 Data public class UserDTO {private Long id;private String nickName;private String icon; }校验是否登录 用户发送请求不止一次所以说登录验证也不止进行一次于是可以使用拦截器完成验证拦截器的使用可分为两步 创建拦截器 /*** author : mereign* date : 2022/5/5 - 10:31* desc : 拦截器实现请求拦截判断登录信息*/ Component public class LoginInterceptor implements HandlerInterceptor {Autowiredprivate StringRedisTemplate stringRedisTemplate;Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 获取请求头中的token信息String token request.getHeader(authorization);if (StrUtil.isBlank(token)) {// token为空返回401未授权状态码拦截response.setStatus(401);return false;}// 根据token获取redis中的用户valueMapObject, Object userMap stringRedisTemplate.opsForHash().entries(RedisConstants.LOGIN_USER_KEY token);HttpSession session request.getSession();// 判断用户是否存在if (userMap.isEmpty()) {// 用户不存在返回401未授权状态码拦截response.setStatus(401);return false;}// 用户存在将hash数据转换为userDTO存信息到ThreadLocalUserDTO userDTO BeanUtil.fillBeanWithMap(userMap, new UserDTO(), false);UserHolder.saveUser(userDTO);// 刷新token有效期放行stringRedisTemplate.expire(RedisConstants.LOGIN_USER_KEY token, RedisConstants.LOGIN_USER_TTL, TimeUnit.MINUTES);return true;}Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {UserHolder.removeUser();} }注册拦截器 /*** author : mereign* date : 2022/5/5 - 10:43* desc :*/ Configuration public class MvcConfig implements WebMvcConfigurer {Autowiredprivate LoginInterceptor loginInterceptor;Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(loginInterceptor).excludePathPatterns(/shop/**,/shop-type/**,/voucher/**,/upload/**,/blog/hot,/user/code,/user/login);} }缓存用户的信息到ThreadLocal中的工具方法 public class UserHolder {private static final ThreadLocalUserDTO 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();} }UserController定义与前端交互 GetMapping(/me) public Result me(){// 获取当前登录的用户并返回UserDTO user UserHolder.getUser();return Result.ok(user); }登录验证优化 由上面的登录验证可知我们对一些需要用户登录验证的功能设置了拦截器如果验证通过会刷新token的有效期这样的话只要用户一直访问我们拦截的功能就可以一直保持token是有效的。但是如果用户登陆之后的操作一直是不需要验证的那也就意味着token的有效期一直不会刷新这样的话30分钟之后token就会失效用户验证就会失败这样显然是不合理的   于是我们可以使用两个拦截器完成最前面的负责拦截所有的请求获取token、从redis中查询用户将查询结果放到ThreadLocal(可能存null)、刷新token有效期最后直接放行后面的拦截器只负责判断有没有从redis中查询到用户他从ThreadLocal获取查询结果判断有则放行无则拦截 创建两个拦截器 /*** author : mereign* date : 2022/5/5 - 10:31* desc : 前置拦截器拦截所有请求前置工作*/ Component public class RefreshTokenInterceptor implements HandlerInterceptor {Autowiredprivate StringRedisTemplate stringRedisTemplate;Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 获取请求头中的token信息String token request.getHeader(authorization);if (StrUtil.isBlank(token)) {// token为空 直接放行return true;}// 根据token获取redis中的用户valueMapObject, Object userMap stringRedisTemplate.opsForHash().entries(RedisConstants.LOGIN_USER_KEY token);HttpSession session request.getSession();// 判断用户是否存在if (userMap.isEmpty()) {// 用户不存在 直接放行return true;}// 用户存在将hash数据转换为userDTO存信息到ThreadLocalUserDTO userDTO BeanUtil.fillBeanWithMap(userMap, new UserDTO(), false);UserHolder.saveUser(userDTO);// 刷新token有效期放行stringRedisTemplate.expire(RedisConstants.LOGIN_USER_KEY token, RedisConstants.LOGIN_USER_TTL, TimeUnit.MINUTES);return true;}Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {UserHolder.removeUser();} }/*** author : mereign* date : 2022/5/5 - 10:31* desc : 登录拦截器拦截需要拦截的请求判断登录信息*/ Component public class LoginInterceptor implements HandlerInterceptor {Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 判断登录if (UserHolder.getUser() null) {response.setStatus(401);return false;}return true;}Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {} }创建完拦截器之后要将两个拦截器通过配置类配置到容器中生效多个拦截器的优先级默认按照添加顺序执行优先级但是也可以使用order方法指定优先级按参数的大小排序优先级参数越小优先级越高 /*** author : mereign* date : 2022/5/5 - 10:43* desc : 配置类注册拦截器*/ Configuration public class MvcConfig implements WebMvcConfigurer {Autowiredprivate RefreshTokenInterceptor refreshTokenInterceptor;Autowiredprivate LoginInterceptor loginInterceptor;Overridepublic void addInterceptors(InterceptorRegistry registry) {// 前置拦截器registry.addInterceptor(refreshTokenInterceptor).addPathPatterns(/**).order(0);// 后置拦截器registry.addInterceptor(loginInterceptor).excludePathPatterns(/shop/**,/voucher/**,/shop-type/**,/upload/**,/blog/hot,/user/code,/user/login).order(1);} }
http://www.pierceye.com/news/48949/

相关文章:

  • 网站服务器设置地点建设施工网络平台
  • 个人做的网站有什么危险吗简单大气好记的公司名
  • 做直播网站收费吗百度推广售后
  • 怎样增加网站会员量深圳设计招聘
  • 做网站赚钱还是做app赚钱正规代运营公司
  • 一个域名可以做多少个二级网站宁波网站建设相信荣胜网络
  • 伪原创php网站镜像同步程序微信怎么制作自己的公众号
  • 成都网站建设028net免费申请qq号不用手机
  • 教育培训类网站模板好的界面建筑网站
  • 上海专业做网站价格seo能从搜索引擎中获得更多的
  • 营口企业网站建设网站建设如何学
  • 学生做爰网站网站建行接口
  • 如何制作自己的网站图?大型网站系统
  • 南昌网站建设公司如何增加网站pr值
  • 网站修改解析怎么做玉环县企业网站建设
  • 网站建设人员叫什么科目dede英文网站
  • 如何选择扬中网站建设文字云网站
  • .net做网站安全吗聊天app开发制作
  • 网站建设的英语怎么说perl做网站
  • 福建省建设厅网站林瑞良创建商城
  • 沧州网站制作的流程wordpress 运行很慢
  • wap站点备份wordpress数据库
  • 做网站麻烦么ftp是专门提供文件传输的网站
  • 宠物店网站建设策划书wordpress 子网站重命名
  • 做翻页电子书的网站做网站的产品图片
  • 什么网站上面能接点小活做临淄建设局网站
  • wordpress网站显示不全python编程代码大全
  • 公司网站建设高端网站建设网页设计织梦 响应式网站
  • 网络营销网站规划建设实训作业余姚网站设计平台
  • ui培训班 千锋教育广州seo外包多少钱