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

30天网站建设实录视频网站运营

30天网站建设实录视频,网站运营,网页版微信手机版,程序员怎么做网站赚钱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是基于内存的读写性能高。 下面基于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要存的是用户对象信息所以value值我们采用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.pierceye.com/news/8762/

相关文章:

  • dnf怎么做提卡网站网站备案通过之后
  • 宝安网站建设定制网页微信能不能传文件
  • 章丘做网站公司百度搜图入口
  • 北京网站设计制作关键词西安市环评建设备案网站
  • 推广型网站建设销售wordpress固定链接去掉index.php
  • 广州网站建设 广州亦客网络百度排行榜前十名
  • 外包网站都有哪些牡丹区住房城乡建设局网站
  • 怎么免费做网站教程福建省住房和城乡建设厅门户网站
  • 一元购网站建设多少钱网页设计与制作论文2000字
  • 深圳市设计网站公司步骤的英文单词
  • 重庆网站建设入门培训网站建设金手指
  • 网页上做网会员网站备案怎么写女孩子做运营是不是压力很大
  • 网站源码采集网站做成小程序
  • 公司需要一个简单的网站网站前台模块包括什么
  • 前程无忧网站开发待遇怎么样山东建设银行官方网站
  • 外贸做哪些网站平台好你认为公司在建立网站时应满足哪些目标
  • 温州市网站制作公司张掖网站建设0936e
  • 建网站公司联系方式广告设计创意作品
  • 网站开发需要多少人可以个人开店的电商平台
  • 企业网站在ps里做吗nginx网站301重定向怎么做
  • 淮南电商网站建设价格上海市住房与城乡建设部网站
  • 泉州seo网站推广做标签网站是什么
  • 邯郸网站设计多少钱wordpress怎么把设置菜单去除
  • 如何提高外贸网站排名成都网站设计哪家比较好
  • 厦门做网站哪家好外贸网站推广 上海
  • 商业网站的网址又拍云存储 wordpress
  • 怎样免费建立自己的网站网站建设演示ppt模板
  • 企业官方网站建设的作用wordpress 在线游戏网站
  • 深圳罗湖做网站的公司哪家好php主做哪种类型网站
  • python做网站快么做网站需要云数据库吗