Sa-Token 是一個輕量級 java 權限認證框架,主要解決登錄認證、權限認證、單點登錄、OAuth2、微服務網關鑒權 等一系列權限相關問題,
Gitee 開源地址:https://gitee.com/dromara/sa-token
本文將詳細介紹 Sa-Token 中的不同 SaSession 物件的區別,以及各種方便的存取值的方法,
一、Session 是什么?
Session 是會話中專業的資料快取組件,通過 Session 我們可以很方便的快取一些高頻讀寫資料,提高程式性能,例如:
// 在登錄時快取user物件
StpUtil.getSession().set("user", user);
// 然后我們就可以在任意處使用這個user物件
SysUser user = (SysUser) StpUtil.getSession().get("user");
在 Sa-Token 中,SaSession 分為三種,分別是:
User-Session: 指的是框架為每個 賬號id 分配的 SaSession,Token-Session: 指的是框架為每個 token 分配的 SaSession,Custom-Session: 指的是以一個 特定的值 作為SessionId,來分配的 Session,
假設三個客戶端登錄同一賬號,且配置了不共享token,那么此時的Session模型是:

簡而言之:
User-Session以UserId為主,只要token指向的UserId一致,那么對應的Session物件就一致,Token-Session以token為主,只要token不同,那么對應的Session物件就不同,Custom-Session以特定的key為主,不同key對應不同的Session物件,同樣的key指向同一個Session物件,
二、獲取 User-Session
有關賬號Session的API如下:
// 獲取當前賬號id的Session (必須是登錄后才能呼叫)
StpUtil.getSession();
// 獲取當前賬號id的Session, 并決定在Session尚未創建時,是否新建并回傳
StpUtil.getSession(true);
// 獲取賬號id為10001的Session
StpUtil.getSessionByLoginId(10001);
// 獲取賬號id為10001的Session, 并決定在Session尚未創建時,是否新建并回傳
StpUtil.getSessionByLoginId(10001, true);
// 獲取SessionId為xxxx-xxxx的Session, 在Session尚未創建時, 回傳null
StpUtil.getSessionBySessionId("xxxx-xxxx");
三、獲取 Token-Session
有關令牌Session的API如下:
// 獲取當前 Token 的 Token-Session 物件
StpUtil.getTokenSession();
// 獲取指定 Token 的 Token-Session 物件
StpUtil.getTokenSessionByToken(token);
四、獲取自定義Session
自定義Session指的是以一個特定的值作為SessionId來分配的Session, 借助自定義Session,你可以為系統中的任意元素分配相應的session
例如以商品id作為key為每個商品分配一個Session,以便于快取和商品相關的資料,其相關API如下:
// 查詢指定key的Session是否存在
SaSessionCustomUtil.isExists("goods-10001");
// 獲取指定key的Session,如果沒有,則新建并回傳
SaSessionCustomUtil.getSessionById("goods-10001");
// 獲取指定key的Session,如果沒有,第二個引數決定是否新建并回傳
SaSessionCustomUtil.getSessionById("goods-10001", false);
// 洗掉指定key的Session
SaSessionCustomUtil.deleteSessionById("goods-10001");
五、在 Session 上存取值
// 寫值
session.set("name", "zhang");
// 寫值 (只有在此key原本無值的時候才會寫入)
session.setDefaultValue("name", "zhang");
// 取值
session.get("name");
// 取值 (指定默認值)
session.get("name", "<defaultValue>");
// 取值 (若無值則執行引數方法, 之后將結果保存到此鍵名下,并回傳此結果 若有值則直接回傳, 無需執行引數方法)
session.get("name", () -> {
return ...;
});
// ---------- 資料型別轉換: ----------
session.getInt("age"); // 取值 (轉int型別)
session.getLong("age"); // 取值 (轉long型別)
session.getString("name"); // 取值 (轉String型別)
session.getDouble("result"); // 取值 (轉double型別)
session.getFloat("result"); // 取值 (轉float型別)
session.getModel("key", Student.class); // 取值 (指定轉換型別)
session.getModel("key", Student.class, <defaultValue>); // 取值 (指定轉換型別, 并指定值為Null時回傳的默認值)
// 是否含有某個key (回傳true或false)
session.has("key");
// 刪值
session.delete('name');
// 清空所有值
session.clear();
// 獲取此 Session 的所有key (回傳Set<String>)
session.keys();
六、其它操作
// 回傳此 Session 的id
session.getId();
// 回傳此 Session 的創建時間 (時間戳)
session.getCreateTime();
// 回傳此 Session 會話上的底層資料物件(如果更新map里的值,請呼叫session.update()方法避免產生臟資料)
session.getDataMap();
// 將這個 Session 從持久庫更新一下
session.update();
// 注銷此 Session 會話 (從持久庫洗掉此Session)
session.logout();
七、SaSession 環境隔離說明
有同學經常會把 SaSession 與 HttpSession 進行混淆,例如:
@PostMapping("/resetPoints")
public void reset(HttpSession session) {
// 在 HttpSession 上寫入一個值
session.setAttribute("name", 66);
// 在 SaSession 進行取值
System.out.println(StpUtil.getSession().get("name")); // 輸出null
}
要點:
SaSession與HttpSession沒有任何關系,在HttpSession上寫入的值,在SaSession中無法取出,HttpSession并未被框架接管,在使用Sa-Token時,請在任何情況下均使用SaSession,不要使用HttpSession,
八、未登錄場景下獲取 Token-Session
默認場景下,只有登錄后才能通過 StpUtil.getTokenSession() 獲取 Token-Session,
如果想要在未登錄場景下獲取 Token-Session ,有兩種方法:
- 方法一:將全域配置項
tokenSessionCheckLogin改為 false, - 方法二:使用匿名 Token-Session
// 獲取當前 Token 的匿名 Token-Session (可在未登錄情況下使用的 Token-Session)
StpUtil.getAnonTokenSession();
注意點:如果前端沒有提交 Token ,或者提交的 Token 是一個無效 Token 的話,框架將不會根據此 Token 創建 Token-Session 物件,
而是隨機一個新的 Token 值來創建 Token-Session 物件,此 Token 值可以通過 StpUtil.getTokenValue() 獲取到,
參考資料
- Sa-Token 檔案:https://sa-token.cc
- Gitee 倉庫地址:https://gitee.com/dromara/sa-token
- GitHub 倉庫地址:https://github.com/dromara/sa-token
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/553819.html
標籤:其他
上一篇:如何用ReadWriteLock實作一個通用的快取中心?
下一篇:返回列表
