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

重庆网站推广哪家好站长工具站长

重庆网站推广哪家好,站长工具站长,空间链接制作网站,群辉怎么进入wordpress后台目录 一.短信登录 1.1 导入项目 1.2 Session 实现短信登录 1.3 集群的 Session 共享问题 1.4 基于 Redis 实现共享 Session 登录 一.短信登录 1.1 导入项目 数据库准备 -- 创建用户表 CREATE TABLE user (id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT 用户ID,phone …

目录

一.短信登录

1.1 导入项目

1.2 Session 实现短信登录

1.3 集群的 Session 共享问题

1.4 基于 Redis 实现共享 Session 登录


一.短信登录

1.1 导入项目

数据库准备

-- 创建用户表

CREATE TABLE `user` (`id` BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '用户ID',`phone` VARCHAR(20) NOT NULL UNIQUE COMMENT '手机号',`nick_name` VARCHAR(50) COMMENT '昵称',`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间'
) COMMENT='用户表';

导入项目

cd nginx目录
start nginx.exe

1.2 Session 实现短信登录

发送验证码

@Override
public Result sendCode(String phone, HttpSession session) {// 校验手机号格式是否正确if (RegexUtils.isPhoneInvalid(phone)) {return Result.fail("手机号格式不正确!");}// 生成6位随机数字验证码String code = RandomUtil.randomNumbers(6);// 将验证码保存到session中session.setAttribute("code", code);// 日志记录验证码(实际开发中应发送短信)log.info("验证码为: " + code);return Result.ok();
}

登录功能

@Override
public Result login(LoginFormDTO loginForm, HttpSession session) {// 获取手机号String phone = loginForm.getPhone();// 校验手机号格式if (RegexUtils.isPhoneInvalid(phone)) {return Result.fail("手机号格式错误!");}// 从session中获取验证码Object cacheCode = session.getAttribute("code");String code = loginForm.getCode();// 校验验证码是否正确if (code == null || !cacheCode.toString().equals(code)) {return Result.fail("验证码错误!");}// 根据手机号查询用户User user = query().eq("phone", phone).one();if (user == null) {// 如果用户不存在,则自动注册user = new User();user.setPhone(phone);user.setNickName("user_" + RandomUtil.randomString(10));save(user);}// 将用户信息存入sessionsession.setAttribute("user", user);return Result.ok();
}

拦截器 LoginInterceptor

public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 获取sessionHttpSession session = request.getSession();// 从session中获取用户信息Object user = session.getAttribute("user");// 判断用户是否存在if (user == null) {// 用户未登录,返回401状态码response.setStatus(401);response.getWriter().write("用户未登录!");return false;}// 用户已登录,放行return true;}
}

在MvcConfig加上拦截器

@Configuration
public class MvcConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoginInterceptor()).excludePathPatterns("/user/code",    // 验证码接口"/user/login",   // 登录接口"/blog/hot",     // 热门博客"/shop/**",      // 商户信息"/shop-type/**", // 商户类型"/upload/**",    // 文件上传"/voucher/**"    // 优惠券);}
}

1.3 集群的 Session 共享问题

多台Tomcat不共享session存储空间,当请求切换到不同的tomcat服务时导致数据丢失的问题

所以我们把数据存入Redis,集群的Redis可以替代session

1.4 基于 Redis 实现共享 Session 登录

我们应该选择String类型存验证码即可,value:验证码,但是key要区分开来

​ 选择Hash存储用户信息,因为每个字段独立,比较好去DRUD,内存占用少,key用token即可(随机字符串)

之前的session的话,tomcat会自动把session的Id存入Cookie,每次请求都会携带Cookie,所以我们需要手动把token返回给客户端,每次请求客户端都会携带着token

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {@Autowiredprivate StringRedisTemplate stringRedisTemplate;@Overridepublic Result sendCode(String phone, HttpSession session) {// 校验手机号格式是否正确if (RegexUtils.isPhoneInvalid(phone)) {return Result.fail("手机号格式不正确!");}// 生成6位随机数字验证码String code = RandomUtil.randomNumbers(6);// 将验证码保存到Redis中,设置过期时间为2分钟stringRedisTemplate.opsForValue().set(RedisConstants.LOGIN_CODE_KEY + phone, code, RedisConstants.LOGIN_CODE_TTL, TimeUnit.MINUTES);// 日志记录验证码(实际开发中应发送短信)log.info("验证码为: " + code);return Result.ok();}
}@Override
public Result login(LoginFormDTO loginForm, HttpSession session) {// 获取手机号String phone = loginForm.getPhone();// 校验手机号格式if (RegexUtils.isPhoneInvalid(phone)) {return Result.fail("手机号格式错误!");}// 从Redis中获取验证码String cacheCode = stringRedisTemplate.opsForValue().get(RedisConstants.LOGIN_CODE_KEY + phone);String code = loginForm.getCode();// 校验验证码是否正确if (cacheCode == null || !cacheCode.equals(code)) {return Result.fail("验证码错误!");}// 根据手机号查询用户User user = query().eq("phone", phone).one();if (user == null) {// 如果用户不存在,则自动注册user = new User();user.setPhone(phone);user.setNickName("user_" + RandomUtil.randomString(10));save(user);}// 生成唯一的TokenString token = UUID.randomUUID().toString(true);// 将用户信息转换为UserDTOUserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);// 将用户信息以Hash类型存储到Redis中,设置过期时间为36000分钟stringRedisTemplate.opsForHash().putAll(RedisConstants.LOGIN_USER_KEY + token, BeanUtil.beanToMap(userDTO));stringRedisTemplate.expire(RedisConstants.LOGIN_USER_KEY + token, RedisConstants.LOGIN_USER_TTL, TimeUnit.MINUTES);// 返回Tokenreturn Result.ok(token);
}

MvcConfig注入stringRedisTemplate,然后传给LoginInterceptor,因为LoginInterceptor不是bean不能用spring注入其他bean

@Configuration
public class MvcConfig implements WebMvcConfigurer {@Resourceprivate StringRedisTemplate stringRedisTemplate;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoginInterceptor(stringRedisTemplate)).excludePathPatterns("/user/code","/user/login","/blog/hot","/shop/**","/shop-type/**","/upload/**","/voucher/**");}
}

LoginInterceptor

public class LoginInterceptor implements HandlerInterceptor{private final 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)){//不存在,拦截 设置响应状态吗为401(未授权)response.setStatus(401);return false;}//2.基于token获取redis中用户String key=RedisConstants.LOGIN_USER_KEY + token;Map<Object, Object> userMap = stringRedisTemplate.opsForHash().entries(key);//3.判断用户是否存在if (userMap.isEmpty()){//4.不存在则拦截,设置响应状态吗为401(未授权)response.setStatus(401);return false;}//5.将查询到的Hash数据转化为UserDTO对象UserDTO userDTO=new UserDTO();BeanUtil.fillBeanWithMap(userMap,userDTO, false);//6.保存用户信息到ThreadLocalUserHolder.saveUser(userDTO);//7.更新token的有效时间,只要用户还在访问我们就需要更新token的存活时间stringRedisTemplate.expire(key, RedisConstants.LOGIN_USER_TTL, TimeUnit.SECONDS);//8.放行return true;}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {//销毁,以免内存泄漏UserHolder.removeUser();}
}

用户请求进去拦截器,我们试着去获取请求头内的token,根据token去查询用户信息,判断是否拦截,保存在ThreadLocal,刷新token的有效期

但是,这个拦截器是拦截需要登录之后才需要进行请求的路径,那我如果一直在访问的是不需要拦截的页面的话,我还是会过期?这就不合理。所以我们需要在这个拦截器前面再加个拦截器,然后在新增拦截器上进行保存ThreadLocal和刷新有效期,不理解其他

其实就是对之前的拦截器进行功能拆分

MvcConfig

@Configuration
public class MvcConfig implements WebMvcConfigurer {@Resourceprivate StringRedisTemplate stringRedisTemplate;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoginInterceptor()).excludePathPatterns("/user/code","/user/login","/blog/hot","/shop/**","/shop-type/**","/upload/**","/voucher/**").order(1);//RefreshTokenInterceptor 先于 LoginInterceptor 执行registry.addInterceptor(new RefreshTokenInterceptor(stringRedisTemplate)).order(0);//默认拦截所有请求}}

RefreshTokenInterceptor

public class RefreshTokenInterceptor implements HandlerInterceptor {private final StringRedisTemplate stringRedisTemplate;public RefreshTokenInterceptor(StringRedisTemplate stringRedisTemplate) {this.stringRedisTemplate = stringRedisTemplate;}@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 从请求头中获取TokenString token = request.getHeader("authorization");if (StrUtil.isBlank(token)) {// 如果Token为空,直接放行return true;}// 构造Redis中的KeyString key = RedisConstants.LOGIN_USER_KEY + token;// 从Redis中获取用户信息Map<Object, Object> userMap = stringRedisTemplate.opsForHash().entries(key);if (userMap.isEmpty()) {// 如果用户信息为空,直接放行return true;}// 将用户信息转换为UserDTO对象UserDTO userDTO = new UserDTO();BeanUtil.fillBeanWithMap(userMap, userDTO, false);// 将用户信息保存到ThreadLocal中UserHolder.saveUser(userDTO);// 刷新Token的有效期stringRedisTemplate.expire(key, RedisConstants.LOGIN_USER_TTL, TimeUnit.MINUTES);return true;}
}

LoginInterceptor

public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 从ThreadLocal中获取用户信息UserDTO user = UserHolder.getUser();if (user == null) {// 如果用户未登录,返回401状态码response.setStatus(401);response.getWriter().write​```

文章转载自:
http://proteinase.c7501.cn
http://complexionless.c7501.cn
http://shibilant.c7501.cn
http://lockean.c7501.cn
http://teleconferencing.c7501.cn
http://assamese.c7501.cn
http://demarch.c7501.cn
http://saurischian.c7501.cn
http://fluerics.c7501.cn
http://pressurization.c7501.cn
http://lighthouseman.c7501.cn
http://trier.c7501.cn
http://gressorial.c7501.cn
http://anticipant.c7501.cn
http://tanto.c7501.cn
http://anenst.c7501.cn
http://schwarzwald.c7501.cn
http://briticism.c7501.cn
http://pokie.c7501.cn
http://odontology.c7501.cn
http://transude.c7501.cn
http://triangular.c7501.cn
http://nursekeeper.c7501.cn
http://slipknot.c7501.cn
http://thieve.c7501.cn
http://consistency.c7501.cn
http://gritstone.c7501.cn
http://pteridine.c7501.cn
http://atherogenic.c7501.cn
http://damyankee.c7501.cn
http://holder.c7501.cn
http://labored.c7501.cn
http://hemachrome.c7501.cn
http://oilcloth.c7501.cn
http://endodontic.c7501.cn
http://mycoplasma.c7501.cn
http://appurtenance.c7501.cn
http://snobby.c7501.cn
http://radiographer.c7501.cn
http://postnuptial.c7501.cn
http://tumbling.c7501.cn
http://franklinite.c7501.cn
http://reframe.c7501.cn
http://pompon.c7501.cn
http://gabrovo.c7501.cn
http://bisulphide.c7501.cn
http://reb.c7501.cn
http://lamehter.c7501.cn
http://silver.c7501.cn
http://untraversed.c7501.cn
http://week.c7501.cn
http://hsien.c7501.cn
http://shamal.c7501.cn
http://sothic.c7501.cn
http://zagreb.c7501.cn
http://funafuti.c7501.cn
http://corticated.c7501.cn
http://cheapie.c7501.cn
http://uninspected.c7501.cn
http://deambulatory.c7501.cn
http://exserviee.c7501.cn
http://slentando.c7501.cn
http://lobworm.c7501.cn
http://pharyngonasal.c7501.cn
http://enzyme.c7501.cn
http://hemocytoblastic.c7501.cn
http://onward.c7501.cn
http://skfros.c7501.cn
http://turkmen.c7501.cn
http://premonish.c7501.cn
http://flavescent.c7501.cn
http://walkyrie.c7501.cn
http://preatomic.c7501.cn
http://noninitial.c7501.cn
http://hearten.c7501.cn
http://portrayer.c7501.cn
http://recommittal.c7501.cn
http://euphoria.c7501.cn
http://sphagnous.c7501.cn
http://rifling.c7501.cn
http://castanets.c7501.cn
http://ethinyl.c7501.cn
http://birdy.c7501.cn
http://telengiscope.c7501.cn
http://olivary.c7501.cn
http://chimere.c7501.cn
http://exclusivism.c7501.cn
http://transvalue.c7501.cn
http://pneumatocele.c7501.cn
http://microbicide.c7501.cn
http://conflictive.c7501.cn
http://botryoid.c7501.cn
http://libate.c7501.cn
http://angular.c7501.cn
http://salse.c7501.cn
http://imprese.c7501.cn
http://falcial.c7501.cn
http://sherris.c7501.cn
http://semifascist.c7501.cn
http://rivalship.c7501.cn
http://www.zhongyajixie.com/news/70446.html

相关文章:

  • 企业网站建设需注意什么网络推广服务外包公司
  • 建设网站人员商丘seo外包
  • 公司装修会计分录优化师
  • 参考效果图网站福州seo视频
  • 个人身份调查网站百度新闻首页新闻全文
  • 网站友情链接如何做数据分析方法
  • 做百度推广得用网站是吗crm系统网站
  • 上海网站建设 美橙微信推广加人
  • 网站制作需要什么资料网站推广应该怎么做?
  • 苏州做网站哪里好线上宣传渠道
  • 哈尔滨网站建设公司网络营销策划公司
  • 石家庄企业网站建设价格微信客户管理
  • 网站开发软件选择网络推广有哪些
  • 织梦做的网站用什么数据库企业建站公司
  • 分红盘网站开发多少钱大连今日新闻头条
  • 一级a做爰小说免费网站百度上首页
  • 网络电商是做什么的seo内容优化心得
  • 建材行业网站建设方案枫树seo网
  • 怎么做网站的域名解析万能搜索网站
  • 有友情链接的网站官网百度
  • 旅游类网站如何做推广旅游景区网络营销案例
  • 网红营销对消费者的影响seo线上培训多少钱
  • 常州手机网站建设长沙网站优化推广方案
  • 网站做404是什么意思建站系统cms
  • 什么网站可以免费做护师题网络营销五种方法
  • 网站长尾词长沙网站开发
  • 有没有做培养基的网站河南整站百度快照优化
  • 网站制作成app百度指数官网移动版
  • 网站建设项目经理的工作微博推广费用
  • 本地资讯网站做的最好的2021年新闻摘抄