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

怎么让别人访问自己做的的网站青岛关键词排名哪家好

怎么让别人访问自己做的的网站,青岛关键词排名哪家好,wordpress seo联接插件,搭建创新平台2023.12.6 短信登陆如果基于session来实现,会存在session共享问题:多台Tomcat不能共享session存储空间,这会导致当请求切换到不同服务器时出现数据丢失的问题。 早期的解决办法是让session提供一个数据拷贝的功能,即让各个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);Map<String, 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_KEY+token;Map<Object, 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.hkea.cn/news/997072/

相关文章:

  • 怎么做装修网站b2b多平台一键发布
  • ASP做网站源代码大专网络营销专业好不好
  • 网络公司网站 优帮云做网站排名服务热线
  • 制作网页设计软件列表案例谷歌seo 优化
  • wordpress网站备案上海搜索推广
  • 网站建设套餐有哪些安卓在线视频嗅探app
  • 做电影网站要买什么重庆seo网站哪家好
  • 广州北京网站建设公司网站外部优化的4大重点
  • 网站建设书优化大师是干什么的
  • 优秀的网站建设公司百度指数人群画像
  • wordpress企业中文模板太原seo哪家好
  • 广东网广东网站建设网站推广方案模板
  • 网站运营知识快手seo
  • 咖啡公司网站建设策划书微信营销方式
  • 柳江区城乡住房建设局网站上海seo优化服务公司
  • 西城企业网站建设企业网站怎么优化
  • 初学者做动态网站项目例子游戏特效培训机构排名
  • 汽车类网站搭建直链平台
  • 做网站遇到的困难总结网络营销软件代理
  • 做网站登录论坛外链代发
  • 东营专业网站建设公司排行青岛谷歌优化公司
  • 公众号和网站先做哪个口碑营销的形式
  • 长沙企业建网站费用关键词搜索推广排行榜
  • 怎么做网站端口代理沧州网络推广外包公司
  • php wordpress 目录seo课程培训机构
  • 常州网站建设方案优化引流app推广软件
  • 网络营销网站建设实训网络营销步骤
  • 网站都有后台吗百度竞价开户公司
  • 秭归网站建设网站seo优化心得
  • wordpress电影网站模板seo运营