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

场景:

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

实现过程:

  1. pom中增加redis和session依赖
1
2
3
4
5
6
7
8
<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
1
2
HttpSession httpSession = request.getSession();
httpSession.setAttribute("user", user);
  1. 把sessionId返回给前端
1
2
3
String sessionId = httpSession.getId();
JSONObject result = new JSONObject();
result.put("sessionId", sessionId);

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

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

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

1
User user = (User) httpSession.getAttribute("user");

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

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

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

1
2
3
4
5
6
7
8
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人,我更新文档进行说明,嘎嘎,大神请飘过。

不足之处请指正。

打赏
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2015-2020 AChampion
  • Powered by Hexo Theme Ayer
  • PV: UV:

开玩笑的~不用打赏