首先,导包。

在pom.xml文件里面加入以下:

<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>

jar包不做多解释了,看那个artifactId的内容应该能知道干啥的。

然后是yml文件:

spring:
redis:
database: 0
host: 127.0.0.1
port: 6379
password:
jedis.pool.max-idle: 100
jedis.pool.max-wait: -1ms
jedis.pool.min-idle: 2
timeout: 2000ms

是的,很精简。

然后是,到你的RedisConfig文件上面,开启redis的session关联注解(其实不用这个注解也是没问题的,后面自己可以去除看看。)

@EnableRedisHttpSession(maxInactiveIntervalInSeconds=60) 这边是设置存入redis里面的值的过期时间。

默认不设置的话,是1800秒即30分钟。

@EnableRedisHttpSession

如:

(Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五_springboot

OK,我们开始共享session咯!

在controller文件里面写2个方法吧,

@GetMapping("/setSessionValue")
public String setredisResult(HttpServletRequest request){
request.getSession().setAttribute(request.getSession().getId(), "---测试数据---"+request.getRequestURL());

System.out.println(request.getSession().getId());
return "set成功,已经存入session域且redis里面也会有值";
}

@GetMapping("/getSessionValue")
public String redisResult(HttpServletRequest request) {
System.out.println(request.getSession().getId());
String value = String.valueOf(request.getSession().getAttribute(request.getSession().getId()));

return "取值成功 :"+value;
}

先运行第一个, 如下:

(Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五_redis_02

控制台打印出sessionid值:

(Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五_session_03

 

然后再瞟一眼redis数据库,是的,没错,可以看到redis也存储了这个session会话的相关信息。 (TTL是过期时间)

(Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五_session_04

(Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五_redis_05

 

然后访问下第二个接口,可以看到根据sessionid作为Key去session域是能正常获取值的,

(Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五_session_06

 

好了,redis实现session共享到此其实已经完毕了!

有人可能会有疑问,怎么体现共享了? 这时候,你如果实现负载均衡,开启两个tomcat服务器,不同端口,然后用通过浏览器通过不同端口去访问,你会发现,通过request.getSession().getId()拿出来的sessionid是一样一样的!

 

那么接下来简单介绍下,使用这个唯一id来实现单点登录:

@GetMapping("/userLogin")
public String setRedisResult(HttpServletRequest request){

//第一次登录

//1. 取出当期客户端的sessionId
String sId=request.getSession().getId();
//2. 查询该sessionId 是否存在于redis
boolean exists = redisUtils.exists(sId);

if (!exists){
//2.1未登录过,进行用户信息的校验
//如果通过后,写入session域进行共享,即使是负载不同端口,sessionId不会发生变化
request.getSession().setAttribute(sId, "login success");
redisUtils.setWithTime(sId,"login success",1000);
return "success login!";

//如果不通过,那么返回登录页面,省略
}else {
//2.2 已经登录过,则存入redis中刷新过期时间,再直接返回成功页面
redisUtils.setWithTime(sId,"login success",1000);
return " yes,you are allow!";
}

}

@GetMapping("/userLoginOut")
public String userLoginOut(HttpServletRequest request){

String sId=request.getSession().getId();
redisUtils.remove(sId);
return "login out!";
}

ps:代码里使用到的工具类RedisUtils

 

可以看到以上情况其实单纯使用redis配合sesionid共享后就能完成单点登录;

题外补充:
但是以上这种情况是使用上了redis的session共享,保证了sessionId不变,所以每次去出来,在有效时间内都是一样的。
既然都讲到了单点登录吗,那么如果单纯使用redis不使用session共享怎么去实现呢?那就是将第一次登录的sessionId保存在浏览器cookise里,这样每次登录通过cookise去拿出头一次固定不变的sessionid,来判断用户是否有登录过。
这种思路实现方案是:

//登录接口
@GetMapping("/userLogin")
public String setRedisResult(HttpServletRequest request, HttpServletResponse response){

//第一次登录

//1. 取出当期客户端的sessionId
String sId=request.getSession().getId();

String cookies = getCookies(request);

if (cookies==null || cookies.equals("")){

System.out.println("没有登录过,准备进行登录!");
//执行登录逻辑

//写入cookie
writeLoginToken(response,sId); //这里设置cookie的过期时间应当与redis设置的时间且与session失效时间保持一致
//写入redis
redisUtils.setWithTime(sId,"userInfo",1000);
System.out.println("登录成功!");
return "success login!";
}else{

boolean exists = redisUtils.exists(cookies);
if (exists){

System.out.println("已经登录过,正常登录!");
return " yes,you are allow!";
}else {

return "信息异常不允许登录";
}
}



}
/**
* 获取浏览器存入
* @param request
* @return
*/
public String getCookies(HttpServletRequest request){
//HttpServletRequest 装请求信息类
//HttpServletRespionse 装相应信息的类

Cookie[] cookies = request.getCookies();
if(cookies != null){
for(Cookie cookie : cookies){
if(cookie.getName().equals("SESSION_ID")){
return cookie.getValue();
}
}
}

return null;
}

/**
*设置浏览器cookie
* @param response
* @param token
*/
public static void writeLoginToken(HttpServletResponse response,String token){
Cookie ck = new Cookie("SESSION_ID",token);
//设置cookie的域
// ck.setDomain("jc.test.com");
// //代表设在根目录
// ck.setPath("/");
//防止脚本读取
ck.setHttpOnly(true);
//单位是秒,设置成-1代表永久,如果cookie不设置maxage的话,cookie就不会写入硬盘,写在内存中,只在当前页面有效
ck.setMaxAge(1000);
response.addCookie(ck);
}

 

就到此吧。