單機session管理
到目前爲止三個功能:
- 用戶名 + 密碼登錄
- 手機號 + 短信登錄
- 社交網站登錄
前兩種使用表單提交方式完成,後一種使用oath授權完成;
雖然表現方式和處理流程不同,但是有一個共同點,認證後的用戶信息是存放在session中的;
- session超時
- 如何管理超時時間
- 超時後如何處理
session併發 : a 機器登錄,又在b機器登錄的場景下,只運行一臺機器登錄
- 如何保持後來者生效,之前的失效
集羣session管理
均衡負載如果沒有做session粘連的話,會出現登錄在a機器,請求數據在b機器
session超時
注意:server.session.timeout 已經過時了
server:
port: 80
servlet:
session:
timeout: 10s
重啓測試,發現並沒有超時;在以下源碼中限制了最小爲1分鐘;
org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory#configureSession
實現session超時提醒
session超時之後,再次訪問進行一個提醒要怎麼做呢?
cn.mrcode.imooc.springsecurity.securitybrowser.BrowserSecurityConfig#configure
配置下session失效跳轉的url地址,這個地址需要我們實現。你可以做任何的業務邏輯;同時記得放行該地址,否則又被攔截授權了
.and()
.sessionManagement()
.invalidSessionUrl("/session/invalid")
cn.mrcode.imooc.springsecurity.securitybrowser.BrowserSecurityController#sessionInvalid
這裏就打印下消息
@GetMapping("/session/invalid")
@ResponseStatus(HttpStatus.UNAUTHORIZED)
public SimpleResponse sessionInvalid() {
String message = "session失效";
return new SimpleResponse(message);
}
實現session併發登錄控制
// 配置地址或則策略類
.maximumSessions(1) //限制同一個用戶只能有一個session登錄
//.expiredUrl("/session/expired") // 也可以跳轉到一個服務
.expiredSessionStrategy(new MySessionInformationExpiredStrategy()) // 失效後的策略。定製型更高,失效前的請求還能拿到
編寫策略類
/**
* session併發登錄失效策略
* @author : zhuqiang
* @version : V1.0
* @date : 2018/8/6 21:28
*/
public class MySessionInformationExpiredStrategy implements SessionInformationExpiredStrategy {
@Override
public void onExpiredSessionDetected(SessionInformationExpiredEvent event) throws IOException, ServletException {
// 該對象能獲取到訪問失效前的url地址
event.getResponse().setContentType("application/json;charset=UTF-8");
event.getResponse().getWriter().write("session併發登錄");
}
}
測試:在不同瀏覽器登錄,然後在最開始登錄的瀏覽器中訪問一個服務查看下;
實現session併發登錄策略2
.maximumSessions(1) //限制同一個用戶只能有一個session登錄
.maxSessionsPreventsLogin(true) // 當session達到最大後,阻止後登錄的行爲
測試會提示:”Maximum sessions of 1 for this principal exceeded”
代碼重構,消除重複代碼,可提供可配置功能
這裏嘗試自己看一遍視頻,然後全程去思考如何提出來。不行的時候再看源碼
重構的時候需要注意一個坑:
/** 當session達到最大值後,是阻止用戶登錄還是剔除掉已登錄用戶
* fasle : 會走{@link cn.mrcode.imooc.springsecurity.securitybrowser.session.MySessionInformationExpiredStrategy}
* true:會阻止登錄,這個阻止登錄的個性化消息沒有設置,看源碼的時候好像可以覆蓋那個過濾器;設置爲true會看到報錯信息,然後就可以查看覆蓋說明了
* */
private boolean maxSessionsPreventsLogin;