Redis 基础 - 短信验证码登录

本文摘要
先简单列出用session方式。然后提出session方式的问题,并简单换为用Redis的方式。最后通过优化来解决一些小问题。

Redis基础 - 基本类型及常用命令

Redis基础 - Java客户端

基于session实现短信登陆的简单流程

发送验证码

前端把手机号传给服务端,后端经过校验后,生成验证码并存入到session中,并通过第三方平台给用户手机发短信验证码。

登陆/注册

前端把登陆用的手机号和刚才接收的验证码传给服务端,后端经过校验后,若没毛病就用手机号去查用户表,没有用户的话给他注册,若有用户,就算是登陆成功。注册/登陆成功后,把用户的部分信息(除去敏感信息)放到session中。
1)校验手机号:是否规范,是否是刚才收到验证码的那个手机号。
2)校验验证码:放入session的验证码与前台传入的验证码比较。

查看用户登陆状态

前台调用服务端提供的相关API,因为请求会带上cookie,cookie里面有sessionid,后端通过sessionID取出相关用户信息。

用拦截器实现

一般来说,这个逻辑写在拦截器。但controller的有些部分可能会也要用到结果,所以有必要把拦截器的结果传给controller里,但要注意线程的安全,所以用ThreadLocal解决,即拦截器里搞到用户信息之后,可以把他保存在ThreadLocal,因为ThreadLocal是线程域对象,每一个进入Tomcat的请求都是一个独立的线程,所以ThreadLocal会在线程内开辟一个内存空间,去保存对应的用户,这样的话每个线程相互不干扰。所以到了controller后从ThreadLocal里取出用户即可。

代码示例:
LoginInterceptor.java

public class LoginInterceptor implements HandlerInterceptor {
   
	@Override
	public boolean preHandle(request,response,) {
   
		// 进入controller之前处理
		HttpSession session = request.getSession();
		Object user = session.getAttribute("user");
		if(user == null) {
   
			// session中用户信息不存在,返回401状态码
			response.setStatus(401);
			return false;
		}
		// 如果session中存在用户信息,用户信息保存到ThreadLocal。由于是保存在当前线程里面的,所以不需要key。
		UserHolder.saveUser((User)user);
		return true;
	}
	@Override
	public void afterCompletion(request,response,) {
   
		// 业务执行完毕后,销毁用户信息,避免内存泄露
		UserHolder.removeUser();
	}
}

UserHolder.java

public class UserHolder {
   

	pviate static final ThreadLocal<User> tl = new ThreadLocal<>();
	
	public static void saveUser(User user) {
   
		t1.set(user);
	}
	public static User getUser() {
   
		returun tl.get();
	}
	public static void removeUser() {
   
		tl.remove();
	}
}

MvcConfig.java

@Configuration
public class MvcConfig implements WebMvcConfigurer {
   

	@Override
	public void addInterceptors(InterceptorRegistry registry) {
   
		registry.addInterceptor(new LoginInterceptor()).excludePathPatterns("/user/login");
	}
}
网友之言
网友1:为啥要使用ThreadLocal?
网友2:方便同一个线程可以重复使用user。

集群的session共享问题以及对应的解决方案

像上面的那样玩,在集群时会出现问题。因为多台Tomcat并不共享session存储空间,当请求切换到不同的Tomcat服务时导致数据丢失的问题。

session的替代方案需要满足的条件
  • 数据共享,这是最重要的,就是因为不共享才导致了刚才的问题。
  • 内存存储,因为session是内存存储,所以读写效率非常高。
  • key、value结构
解决方案 - 使用Redis

因为Redis是Tomcat以外的存取方案,所以任何一台Tomcat都能访问到Redis,所以就能实现数据共享。而且Redis是内存存储,性能非常强,读写延时基本都是微妙级别。Red

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值