Sa-Token記住我模式實(shí)現(xiàn)七天免登錄
一、需求分析
如圖所示,一般網(wǎng)站的登錄界面都會(huì)有一個(gè) [記住我]
按鈕,當(dāng)你勾選它登錄后,即使你關(guān)閉瀏覽器再次打開網(wǎng)站,也依然會(huì)處于登錄狀態(tài),無須重復(fù)驗(yàn)證密碼:
本文將詳細(xì)介紹在 Sa-Token中,如何做到以下登錄模式:
- 記住我登錄:登錄后關(guān)閉瀏覽器,再次打開網(wǎng)站登錄狀態(tài)依然有效,無需重復(fù)登錄。
- 僅本次有效登錄:登錄后關(guān)閉瀏覽器,再次打開網(wǎng)站登錄狀態(tài)將失效,需要再次登錄。
- 七天免登錄:為登錄狀態(tài)設(shè)定一個(gè)詳細(xì)的有效期,在這個(gè)期限內(nèi)無需重復(fù)登錄,過了期限后需要再次登錄。
Sa-Token 是一個(gè)輕量級(jí) java 權(quán)限認(rèn)證框架,主要解決登錄認(rèn)證、權(quán)限認(rèn)證、單點(diǎn)登錄、OAuth2、微服務(wù)網(wǎng)關(guān)鑒權(quán) 等一系列權(quán)限相關(guān)問題。
Gitee 開源地址:https://gitee.com/dromara/sa-token
首先在項(xiàng)目中引入 Sa-Token 依賴:
<!-- Sa-Token 權(quán)限認(rèn)證 --> <dependency> <groupId>cn.dev33</groupId> <artifactId>sa-token-spring-boot-starter</artifactId> <version>1.34.0</version> </dependency>
注:如果你使用的是 SpringBoot 3.x
,只需要將 sa-token-spring-boot-starter
修改為 sa-token-spring-boot3-starter
即可。
二、在 Sa-Token 中實(shí)現(xiàn)記住我功能
Sa-Token的登錄授權(quán),默認(rèn)就是[記住我]
模式,為了實(shí)現(xiàn)[非記住我]
模式,你需要在登錄時(shí)如下設(shè)置:
// 設(shè)置登錄賬號(hào)id為10001,第二個(gè)參數(shù)指定是否為[記住我],當(dāng)此值為false后,關(guān)閉瀏覽器后再次打開需要重新登錄 StpUtil.login(10001, false);
那么,Sa-Token實(shí)現(xiàn)[記住我]
的具體原理是?
三、實(shí)現(xiàn)原理
Cookie作為瀏覽器提供的默認(rèn)會(huì)話跟蹤機(jī)制,其生命周期有兩種形式,分別是:
- 臨時(shí)Cookie:有效期為本次會(huì)話,只要關(guān)閉瀏覽器窗口,Cookie就會(huì)消失。
- 持久Cookie:有效期為一個(gè)具體的時(shí)間,在時(shí)間未到期之前,即使用戶關(guān)閉了瀏覽器Cookie也不會(huì)消失。
利用Cookie的此特性,我們便可以輕松實(shí)現(xiàn) [記住我] 模式:
- 勾選 [記住我] 按鈕時(shí):調(diào)用
StpUtil.login(10001, true)
,在瀏覽器寫入一個(gè)持久Cookie
儲(chǔ)存 Token,此時(shí)用戶即使重啟瀏覽器 Token 依然有效。 - 不勾選 [記住我] 按鈕時(shí):調(diào)用
StpUtil.login(10001, false)
,在瀏覽器寫入一個(gè)臨時(shí)Cookie
儲(chǔ)存 Token,此時(shí)用戶在重啟瀏覽器后 Token 便會(huì)消失,導(dǎo)致會(huì)話失效。
動(dòng)態(tài)演示圖:
四、前后端分離模式下如何實(shí)現(xiàn)[記住我]?
此時(shí)機(jī)智的你??很快發(fā)現(xiàn)一個(gè)問題,Cookie雖好,卻無法在前后端分離環(huán)境下使用,那是不是代表上述方案在APP、小程序等環(huán)境中無效?
準(zhǔn)確的講,答案是肯定的,任何基于Cookie的認(rèn)證方案在前后端分離環(huán)境下都會(huì)失效(原因在于這些客戶端默認(rèn)沒有實(shí)現(xiàn)Cookie功能),不過好在,這些客戶端一般都提供了替代方案,
唯一遺憾的是,此場景中token的生命周期需要我們在前端手動(dòng)控制:
以經(jīng)典跨端框架 uni-app 為例,我們可以使用如下方式達(dá)到同樣的效果:
// 使用本地存儲(chǔ)保存token,達(dá)到 [持久Cookie] 的效果 uni.setStorageSync("satoken", "xxxx-xxxx-xxxx-xxxx-xxx"); // 使用globalData保存token,達(dá)到 [臨時(shí)Cookie] 的效果 getApp().globalData.satoken = "xxxx-xxxx-xxxx-xxxx-xxx";
如果你決定在PC瀏覽器環(huán)境下進(jìn)行前后端分離模式開發(fā),那么更加簡單:
// 使用 localStorage 保存token,達(dá)到 [持久Cookie] 的效果 localStorage.setItem("satoken", "xxxx-xxxx-xxxx-xxxx-xxx"); // 使用 sessionStorage 保存token,達(dá)到 [臨時(shí)Cookie] 的效果 sessionStorage.setItem("satoken", "xxxx-xxxx-xxxx-xxxx-xxx");
Remember me, it's too easy!
五、登錄時(shí)指定 Token 有效期
登錄時(shí)不僅可以指定是否為[記住我]
模式,還可以指定一個(gè)特定的時(shí)間作為 Token 有效時(shí)長,如下示例:
// 示例1: // 指定token有效期(單位: 秒),如下所示token七天有效 StpUtil.login(10001, new SaLoginModel().setTimeout(60 * 60 * 24 * 7)); // ----------------------- 示例2:所有參數(shù) // `SaLoginModel`為登錄參數(shù)Model,其有諸多參數(shù)決定登錄時(shí)的各種邏輯,例如: StpUtil.login(10001, new SaLoginModel() .setDevice("PC") // 此次登錄的客戶端設(shè)備類型, 用于[同端互斥登錄]時(shí)指定此次登錄的設(shè)備類型 .setIsLastingCookie(true) // 是否為持久Cookie(臨時(shí)Cookie在瀏覽器關(guān)閉時(shí)會(huì)自動(dòng)刪除,持久Cookie在重新打開后依然存在) .setTimeout(60 * 60 * 24 * 7) // 指定此次登錄token的有效期, 單位:秒 (如未指定,自動(dòng)取全局配置的 timeout 值) .setToken("xxxx-xxxx-xxxx-xxxx") // 預(yù)定此次登錄的生成的Token .setIsWriteHeader(false) // 是否在登錄后將 Token 寫入到響應(yīng)頭 );
注:如果在登錄時(shí)未指定 new SaLoginModel().setTimeout(604800)
那么框架將采用全局配置的 sa-token.timeout
值作為 Token 的有效期。
六、不同登錄策略的代碼對比
以下是三種登錄策略的代碼差異:
package com.pj.cases.up; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.util.SaResult; /** * Sa-Token 記住我模式登錄 * * @author kong * @since 2022-10-17 */ @RestController @RequestMapping("/RememberMe/") public class RememberMeController { // 記住我登錄 ---- http://localhost:8081/RememberMe/doLogin?name=zhang&pwd=123456 @RequestMapping("doLogin") public SaResult doLogin(String name, String pwd) { if("zhang".equals(name) && "123456".equals(pwd)) { StpUtil.login(10001, true); return SaResult.ok("登錄成功"); } return SaResult.error("登錄失敗"); } // 不記住我登錄 ---- http://localhost:8081/RememberMe/doLogin2?name=zhang&pwd=123456 @RequestMapping("doLogin2") public SaResult doLogin2(String name, String pwd) { if("zhang".equals(name) && "123456".equals(pwd)) { StpUtil.login(10001, false); return SaResult.ok("登錄成功"); } return SaResult.error("登錄失敗"); } // 七天免登錄 ---- http://localhost:8081/RememberMe/doLogin3?name=zhang&pwd=123456 @RequestMapping("doLogin3") public SaResult doLogin3(String name, String pwd) { if("zhang".equals(name) && "123456".equals(pwd)) { StpUtil.login(10001, 60 * 60 * 24 * 7); return SaResult.ok("登錄成功"); } return SaResult.error("登錄失敗"); } }
可依次訪問注釋中提供的測試鏈接,觀察不同登錄策略帶來的會(huì)話有效期差異。
參考資料
- Sa-Token 文檔:https://sa-token.cc
- Gitee 倉庫地址:https://gitee.com/dromara/sa-token
- GitHub 倉庫地址:https://github.com/dromara/sa-token
以上就是Sa-Token記住我模式實(shí)現(xiàn)七天免登錄的詳細(xì)內(nèi)容,更多關(guān)于Sa-Token七天免登錄的資料請關(guān)注腳本之家其它相關(guān)文章!
- 一文學(xué)會(huì)使用sa-token解決網(wǎng)站權(quán)限驗(yàn)證
- 初識(shí)sa-token及登錄授權(quán)簡單實(shí)現(xiàn)
- Sa-Token中的SaSession對象使用學(xué)習(xí)示例詳解
- Sa-Token不同模式實(shí)現(xiàn)單地登錄?多地登錄?同端互斥登錄
- springboot 整合 sa-token簡介及入門教程
- SpringBoot?使用?Sa-Token?完成注解鑒權(quán)功能(權(quán)限校驗(yàn))
- Java輕量級(jí)權(quán)限認(rèn)證框架Sa-Token的使用
- sa-token?路由攔截式鑒權(quán)使用示例詳解
相關(guān)文章
mybatis?resultMap之collection聚集兩種實(shí)現(xiàn)方式
本文主要介紹了mybatis?resultMap之collection聚集兩種實(shí)現(xiàn)方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-09-09如何解決Idea沒有elementui標(biāo)簽的代碼提示問題
這篇文章主要介紹了如何解決Idea沒有elementui標(biāo)簽的代碼提示問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-04-04Eclipse搭建spring開發(fā)環(huán)境圖文教程(推薦)
下面小編就為大家?guī)硪黄狤clipse搭建spring開發(fā)環(huán)境圖文教程(推薦)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-07-07PowerJob的DatabaseMonitorAspect源碼流程
這篇文章主要為大家介紹了PowerJob的DatabaseMonitorAspect源碼流程解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01Java中優(yōu)先隊(duì)列PriorityQueue常用方法示例
這篇文章主要介紹了Java中優(yōu)先隊(duì)列PriorityQueue常用方法示例,PriorityQueue是一種特殊的隊(duì)列,滿足隊(duì)列的“隊(duì)尾進(jìn)、隊(duì)頭出”條件,但是每次插入或刪除元素后,都對隊(duì)列進(jìn)行調(diào)整,使得隊(duì)列始終構(gòu)成最小堆(或最大堆),需要的朋友可以參考下2023-09-09Java練手小項(xiàng)目實(shí)現(xiàn)一個(gè)項(xiàng)目管理系統(tǒng)
讀萬卷書不如行萬里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用Java實(shí)現(xiàn)一個(gè)項(xiàng)目管理系統(tǒng),大家可以在過程中查缺補(bǔ)漏,提升水平2021-10-10