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的方式。java

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

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

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

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

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

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

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是解决的关键点,至因而如何找到它,有两种方法:bash

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

欢迎交流,不足之处请你们指正。服务器

欢迎访问个人blog championjing.github.io/

相关文章
相关标签/搜索