spring-session實現session共享案例(單點登錄)


  參考文章:

  SpringSecurity基礎功能詳解本文代碼基於該篇文章,下面有git地址

  linux下安裝redis步驟

  redis的啟動與關閉以及客戶端連接

  一、項目構建

  1、案例說明

  本文主要演示單點登錄功能,會貼出主要配置和代碼以及必要解釋,全部代碼請參考git地址。session共享一個基本原則是將session存儲在某個地方,所有的應用都可以訪問,這里使用redis存儲session。當應用需要認證時,先從redis讀取用戶信息。

  2、基本配置

  1)pom.xml

<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session</artifactId>
    <version>1.3.1.RELEASE</version>
</dependency>

  2)application.properties

server.port=8080
spring.session.store-type = redis
spring.redis.host=192.168.7.151
spring.redis.port=6379
   

  本案例的兩個應用完全一樣,一個端口是8080,一個端口是80

  3、代碼變動

  1)新增SimpleImageCode.java

public class SimpleImageCode implements Serializable{

    private static final long serialVersionUID = 1L;
    private String code;
    private LocalDateTime expireTime;
    
    public SimpleImageCode(String code,LocalDateTime expireTime) {
        this.code = code;
        this.expireTime = expireTime;
    }
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    public LocalDateTime getExpireTime() {
        return expireTime;
    }
    public void setExpireTime(LocalDateTime expireTime) {
        this.expireTime = expireTime;
    }
    public boolean isExpried() {
        return LocalDateTime.now().isAfter(expireTime);
    }
}

  該類與ImageCode.java基本一樣,區別1:實現了Serializable接口;區別2:沒有BufferedImage屬性。原因是圖形驗證碼要放入session中,而session需要存放到redis中,所以必須實現序列化接口。一個類實現序列化接口,它里面的類屬性也要實現序列化接口,但是BufferedImage是jdk的類,無法實現序列化接口,這樣就不把它放入到redis中,在校驗時,我么只會校驗驗證碼和過期時間,所以不會影響。

  2)修改ValidateCodeController.java

@GetMapping("/code/image")
public void createCode(HttpServletRequest request,HttpServletResponse response) throws Exception {    
        ImageCode imageCode = createImageCode(request);
        SimpleImageCode simpleImageCode = new SimpleImageCode(imageCode.getCode(),imageCode.getExpireTime());
        //request.getSession().setAttribute("imageCodeSession", imageCode);
        request.getSession().setAttribute("imageCodeSession", simpleImageCode);//序列化到redis中
        ImageIO.write(imageCode.getImage(), "JPEG", response.getOutputStream());
 }

  將SimpleImageCode放入到session中

  3)修改ValidateCodeFilter.java

private void validate(HttpServletRequest request){
  //ImageCode codeInSession = (ImageCode)request.getSession().getAttribute("imageCodeSession");
     SimpleImageCode codeInSession = (SimpleImageCode)request.getSession().getAttribute("imageCodeSession");
     String codeInRequest = request.getParameter("imageCode");
     ... ...//校驗邏輯 
     request.getSession().removeAttribute("imageCodeSession");
    }

  校驗驗證碼前從session中取出SimpleImageCode

  二、測試驗證

  1)啟動redis、80端口應用、8080端口應用,查看redis信息為空,如下:

  

  2)瀏覽器輸入:localhost:8080/index.html,跳轉登錄頁面,查看redis,如下:

  

  3)登錄后,查看redis,如下:

  

  4)同一個瀏覽器輸入:localhost/index.html,直接跳到index頁面,查看redis,如下:

  

  5)點擊index.html中的退出連接,查看redis,如下:

  

  6)再次訪問localhost:8080/index.html,跳轉登錄頁面,查看redis,如下:

  

  7)再次登錄8080的應用,查看redis,如下:

  

  通過測試發現實現了單點登錄。貼出截圖只是說明session存在了redis中,並且會隨着操作變化。實際無需關心redis。

 

 

 

 

 

 

 

 

 

 

 

  

  

  

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM