Redis實現Session共享與單點登錄
首先,導包。
在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
如:
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; }
先運行第一個, 如下:
控制臺打印出sessionid值:
然後再瞟一眼redis數據庫,是的,沒錯,可以看到redis也存儲瞭這個session會話的相關信息。 (TTL是過期時間)
然後訪問下第二個接口,可以看到根據sessionid作為Key去session域是能正常獲取值的,
好瞭,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 "信息異常不允許登錄"; } } }
到此這篇關於Redis實現Session共享與單點登錄的文章就介紹到這瞭,更多相關Redis Session共享與單點登錄內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Redis快速實現分佈式session的方法詳解
- SpringBoot+SpringSession+Redis實現session共享及唯一登錄示例
- SpringBoot整合SpringSession實現分佈式登錄詳情
- java開發web前端cookie session及token會話機制詳解
- Java Session會話追蹤原理深入分析