redis session时,sessionId作为token,可靠实现

场景:

在一些不能使用session,或者session不能保持的情况,通常服务器端产生一个token字符串标识用户登录状态。当前端调用后端接口时,将此token作为参数加入到请求中,这样能够避免依赖浏览器与服务端会话状态。token身份验证可用于多域名间保持用户状态,后端负载均衡非ip hash策略等情况。

实现过程:

  1. pom中增加redis和session依赖
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
        </dependency>
复制代码
  1. 在登陆过程中将用户信息和其他需要的信息放入session
	HttpSession httpSession = request.getSession();
	httpSession.setAttribute("user", user);
复制代码
  1. 把sessionId返回给前端
    String sessionId = httpSession.getId();
    JSONObject result = new JSONObject();
    result.put("sessionId", sessionId);
复制代码

这样的流程就是经常使用session的方式。

token(sessionId)使用过程(重点)

重点是从session中获取user的过程,在接收到前端请求时,常见获取user的实现代码:

User user = (User) httpSession.getAttribute("user");
复制代码

但是这样就没有token什么事了,并没有是使用token来做验证。如果要想使用token(sessionId)获取到user,第一个想法就是直接从使用redisTemplate的hash操作,根据key获取到里面的内容,查看一下redis存储session的key,如图:

这里获取还要注意序列化的问题,只有使用相同方式序列化key后才能获取到值。

这种方式想想就很复杂,难道没有简洁的方式获取到这些值吗,存进去的时候挺简单,拿出来时候不能这么麻烦吧。本着对spring强大的信心,寻找到了一个bean: RedisOperationsSessionRepository redisOperationsSessionRepository; 看到这个类的名字就很亲切,猜想一定它一定能够解决问题。通过自动注入,然后调用方法,得出以下代码:

Session session=redisOperationsSessionRepository.findById(sessionId);
if(session==null){
throw new ForbidException("请重新登录");
}
user=session.getAttribute("user");
if(user==null){
redisOperationsSessionRepository.deleteById(sessionId);
}
复制代码

注意这里的session是org.springframework.session.Session,而不是javax.servlet.http.HttpSession(常用的那个session),但是两者有着密切关系,通过适配器模式,将javax.servlet.http.HttpSession转为org.springframework.session.Session。

这样就能很方便的通过这个token(sessionId)获取到存储在redis的session的信息。

这里显然RedisOperationsSessionRepository是解决的关键点,至于是如何找到它,有两种方法:

  • 第一种,看spring-session-data-redis和spring-session-core源码,找到关键点,这种方法估计会多花3个小时的时间;
  • 第二种,最简单直接,而且在找到之后再看源码会更清晰,如果感兴趣的话,评论超过5人,我更新文档进行说明,嘎嘎,大神请飘过,或指教。

欢迎交流,不足之处请大家指正。

欢迎访问我的blog championjing.github.io/

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值