新聞中心
Sa-Token 介紹
Sa-Token 是一個(gè)輕量級(jí) Java 權(quán)限認(rèn)證框架,主要解決:登錄認(rèn)證、權(quán)限認(rèn)證、單點(diǎn)登錄、OAuth2.0、分布式Session會(huì)話、微服務(wù)網(wǎng)關(guān)鑒權(quán) 等一系列權(quán)限相關(guān)問(wèn)題。

堅(jiān)守“ 做人真誠(chéng) · 做事靠譜 · 口碑至上 · 高效敬業(yè) ”的價(jià)值觀,專業(yè)網(wǎng)站建設(shè)服務(wù)10余年為成都成都生料攪拌車小微創(chuàng)業(yè)公司專業(yè)提供企業(yè)網(wǎng)站建設(shè)營(yíng)銷網(wǎng)站建設(shè)商城網(wǎng)站建設(shè)手機(jī)網(wǎng)站建設(shè)小程序網(wǎng)站建設(shè)網(wǎng)站改版,從內(nèi)容策劃、視覺設(shè)計(jì)、底層架構(gòu)、網(wǎng)頁(yè)布局、功能開發(fā)迭代于一體的高端網(wǎng)站建設(shè)服務(wù)。
Sa-Token 旨在以簡(jiǎn)單、優(yōu)雅的方式完成系統(tǒng)的權(quán)限認(rèn)證部分,以登錄認(rèn)證為例,你只需要:
// 會(huì)話登錄,參數(shù)填登錄人的賬號(hào)id
StpUtil.login(10001);無(wú)需實(shí)現(xiàn)任何接口,無(wú)需創(chuàng)建任何配置文件,只需要這一句靜態(tài)代碼的調(diào)用,便可以完成會(huì)話登錄認(rèn)證。
如果一個(gè)接口需要登錄后才能訪問(wèn),我們只需調(diào)用以下代碼:
// 校驗(yàn)當(dāng)前客戶端是否已經(jīng)登錄,如果未登錄則拋出 `NotLoginException` 異常
StpUtil.checkLogin();在 Sa-Token 中,大多數(shù)功能都可以一行代碼解決:
踢人下線:
// 將賬號(hào)id為 10077 的會(huì)話踢下線
StpUtil.kickout(10077);權(quán)限認(rèn)證:
// 注解鑒權(quán):只有具備 `user:add` 權(quán)限的會(huì)話才可以進(jìn)入方法
@SaCheckPermission("user:add")
public String insert(SysUser user) {
// ...
return "用戶增加";
}路由攔截鑒權(quán):
// 根據(jù)路由劃分模塊,不同模塊不同鑒權(quán)
registry.addInterceptor(new SaInterceptor(handler -> {
SaRouter.match("/user/**", r -> StpUtil.checkPermission("user"));
SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
SaRouter.match("/goods/**", r -> StpUtil.checkPermission("goods"));
SaRouter.match("/orders/**", r -> StpUtil.checkPermission("orders"));
SaRouter.match("/notice/**", r -> StpUtil.checkPermission("notice"));
// 更多模塊...
})).addPathPatterns("/**");當(dāng)你受夠 Shiro、SpringSecurity 等框架的三拜九叩之后,你就會(huì)明白,相對(duì)于這些傳統(tǒng)老牌框架,Sa-Token 的 API 設(shè)計(jì)是多么的簡(jiǎn)單、優(yōu)雅!
Sa-Token 功能一覽
Sa-Token 目前主要五大功能模塊:登錄認(rèn)證、權(quán)限認(rèn)證、單點(diǎn)登錄、OAuth2.0、微服務(wù)鑒權(quán)。
- 登錄認(rèn)證 —— 單端登錄、多端登錄、同端互斥登錄、七天內(nèi)免登錄
- 權(quán)限認(rèn)證 —— 權(quán)限認(rèn)證、角色認(rèn)證、會(huì)話二級(jí)認(rèn)證
- Session會(huì)話 —— 全端共享Session、單端獨(dú)享Session、自定義Session
- 踢人下線 —— 根據(jù)賬號(hào)id踢人下線、根據(jù)Token值踢人下線
- 賬號(hào)封禁 —— 登錄封禁、按照業(yè)務(wù)分類封禁、按照處罰階梯封禁
- 持久層擴(kuò)展 —— 可集成Redis、Memcached等專業(yè)緩存中間件,重啟數(shù)據(jù)不丟失
- 分布式會(huì)話 —— 提供jwt集成、共享數(shù)據(jù)中心兩種分布式會(huì)話方案
- 微服務(wù)網(wǎng)關(guān)鑒權(quán) —— 適配Gateway、ShenYu、Zuul等常見網(wǎng)關(guān)的路由攔截認(rèn)證
- 單點(diǎn)登錄 —— 內(nèi)置三種單點(diǎn)登錄模式:無(wú)論是否跨域、是否共享Redis,都可以搞定
- OAuth2.0認(rèn)證 —— 輕松搭建 OAuth2.0 服務(wù),支持openid模式
- 二級(jí)認(rèn)證 —— 在已登錄的基礎(chǔ)上再次認(rèn)證,保證安全性
- Basic認(rèn)證 —— 一行代碼接入 Http Basic 認(rèn)證
- 獨(dú)立Redis —— 將權(quán)限緩存與業(yè)務(wù)緩存分離
- 臨時(shí)Token認(rèn)證 —— 解決短時(shí)間的Token授權(quán)問(wèn)題
- 模擬他人賬號(hào) —— 實(shí)時(shí)操作任意用戶狀態(tài)數(shù)據(jù)
- 臨時(shí)身份切換 —— 將會(huì)話身份臨時(shí)切換為其它賬號(hào)
- 前后臺(tái)分離 —— APP、小程序等不支持Cookie的終端
- 同端互斥登錄 —— 像QQ一樣手機(jī)電腦同時(shí)在線,但是兩個(gè)手機(jī)上互斥登錄
- 多賬號(hào)認(rèn)證體系 —— 比如一個(gè)商城項(xiàng)目的user表和admin表分開鑒權(quán)
- Token風(fēng)格定制 —— 內(nèi)置六種Token風(fēng)格,還可:自定義Token生成策略、自定義Token前綴
- 注解式鑒權(quán) —— 優(yōu)雅的將鑒權(quán)與業(yè)務(wù)代碼分離
- 路由攔截式鑒權(quán) —— 根據(jù)路由攔截鑒權(quán),可適配restful模式
- 自動(dòng)續(xù)簽 —— 提供兩種Token過(guò)期策略,靈活搭配使用,還可自動(dòng)續(xù)簽
- 會(huì)話治理 —— 提供方便靈活的會(huì)話查詢接口
- 記住我模式 —— 適配[記住我]模式,重啟瀏覽器免驗(yàn)證
- 密碼加密 —— 提供密碼加密模塊,可快速M(fèi)D5、SHA1、SHA256、AES、RSA加密
- 全局偵聽器 —— 在用戶登陸、注銷、被踢下線等關(guān)鍵性操作時(shí)進(jìn)行一些AOP操作
- 開箱即用 —— 提供SpringMVC、WebFlux等常見web框架starter集成包,真正的開箱即用
SpringBoot 集成 Sa-Token
一、添加maven依賴
cn.dev33
sa-token-spring-boot-starter
1.34.0
注:如果你使用的 SpringBoot 3.x,只需要將 sa-token-spring-boot-starter 修改為 sa-token-spring-boot3-starter 即可。
二、設(shè)置配置文件
你可以零配置啟動(dòng)項(xiàng)目 ,但同時(shí)你也可以在 application.yml 中增加如下配置,定制性使用框架:
server:
# 端口
port: 8081
############## Sa-Token 配置 (文檔: https://sa-token.cc) ##############
sa-token:
# token名稱 (同時(shí)也是cookie名稱)
token-name: satoken
# token有效期,單位s 默認(rèn)30天, -1代表永不過(guò)期
timeout: 2592000
# token臨時(shí)有效期 (指定時(shí)間內(nèi)無(wú)操作就視為token過(guò)期) 單位: 秒
activity-timeout: -1
# 是否允許同一賬號(hào)并發(fā)登錄 (為true時(shí)允許一起登錄, 為false時(shí)新登錄擠掉舊登錄)
is-concurrent: true
# 在多人登錄同一賬號(hào)時(shí),是否共用一個(gè)token (為true時(shí)所有登錄共用一個(gè)token, 為false時(shí)每次登錄新建一個(gè)token)
is-share: true
# token風(fēng)格
token-style: uuid
# 是否輸出操作日志
is-log: false三、創(chuàng)建案例
@RestController
@RequestMapping("/user/")
public class UserController {
// 測(cè)試登錄,瀏覽器訪問(wèn):http://localhost:8081/user/doLogin?username=zhang&password=123456
@RequestMapping("doLogin")
public String doLogin(String username, String password) {
// 此處僅作模擬示例,真實(shí)項(xiàng)目需要從數(shù)據(jù)庫(kù)中查詢數(shù)據(jù)進(jìn)行比對(duì)
if("iron".equals(username) && "123456".equals(password)) {
StpUtil.login(10001);
return "登錄成功";
}
return "登錄失敗";
}
// 查詢登錄狀態(tài),瀏覽器訪問(wèn):http://localhost:8081/user/isLogin
@RequestMapping("isLogin")
public String isLogin() {
return "當(dāng)前會(huì)話是否登錄:" + StpUtil.isLogin();
}
}登錄認(rèn)證
設(shè)計(jì)思路
對(duì)于一些登錄之后才能訪問(wèn)的接口(例如:查詢我的賬號(hào)資料),我們通常的做法是增加一層接口校驗(yàn):
- 如果校驗(yàn)通過(guò),則:正常返回?cái)?shù)據(jù)。
- 如果校驗(yàn)未通過(guò),則:拋出異常,告知其需要先進(jìn)行登錄。
那么,判斷會(huì)話是否登錄的依據(jù)是什么?我們先來(lái)簡(jiǎn)單分析一下登錄訪問(wèn)流程:
- 用戶提交 name + password 參數(shù),調(diào)用登錄接口。
- 登錄成功,返回這個(gè)用戶的 Token 會(huì)話憑證。
- 用戶后續(xù)的每次請(qǐng)求,都攜帶上這個(gè) Token。
- 服務(wù)器根據(jù) Token 判斷此會(huì)話是否登錄成功。
所謂登錄認(rèn)證,指的就是服務(wù)器校驗(yàn)賬號(hào)密碼,為用戶頒發(fā) Token 會(huì)話憑證的過(guò)程,這個(gè) Token 也是我們后續(xù)判斷會(huì)話是否登錄的關(guān)鍵所在。
登錄與注銷
根據(jù)以上思路,我們需要一個(gè)會(huì)話登錄的函數(shù):
// 會(huì)話登錄:參數(shù)填寫要登錄的賬號(hào)id,建議的數(shù)據(jù)類型:long | int | String, 不可以傳入復(fù)雜類型,如:User、Admin 等等
StpUtil.login(Object id);只此一句代碼,便可以使會(huì)話登錄成功,實(shí)際上,Sa-Token 在背后做了大量的工作,包括但不限于:
- 檢查此賬號(hào)是否之前已有登錄
- 為賬號(hào)生成 Token 憑證與 Session 會(huì)話
- 通知全局偵聽器,xx 賬號(hào)登錄成功
- 將 Token 注入到請(qǐng)求上下文
- 等等其它工作……
你暫時(shí)不需要完整的了解整個(gè)登錄過(guò)程,你只需要記住關(guān)鍵一點(diǎn):Sa-Token 為這個(gè)賬號(hào)創(chuàng)建了一個(gè)Token憑證,且通過(guò) Cookie 上下文返回給了前端。
所以一般情況下,我們的登錄接口代碼,會(huì)大致類似如下:
// 會(huì)話登錄接口
@RequestMapping("doLogin")
public SaResult doLogin(String name, String pwd) {
// 第一步:比對(duì)前端提交的賬號(hào)名稱、密碼
if("iron".equals(name) && "123456".equals(pwd)) {
// 第二步:根據(jù)賬號(hào)id,進(jìn)行登錄
StpUtil.login(10001);
return SaResult.ok("登錄成功");
}
return SaResult.error("登錄失敗");
}如果你對(duì)以上代碼閱讀沒(méi)有壓力,你可能會(huì)注意到略顯奇怪的一點(diǎn):此處僅僅做了會(huì)話登錄,但并沒(méi)有主動(dòng)向前端返回 Token 信息。是因?yàn)椴恍枰獑???yán)格來(lái)講是需要的,只不過(guò) StpUtil.login(id) 方法利用了 Cookie 自動(dòng)注入的特性,省略了你手寫返回 Token 的代碼。
如果你對(duì) Cookie 功能還不太了解,也不用擔(dān)心,我們會(huì)在之后的 [ 前后端分離 ] 章節(jié)中詳細(xì)的闡述 Cookie 功能,現(xiàn)在你只需要了解最基本的兩點(diǎn):
- Cookie 可以從后端控制往瀏覽器中寫入 Token 值。
- Cookie 會(huì)在前端每次發(fā)起請(qǐng)求時(shí)自動(dòng)提交 Token 值。
因此,在 Cookie 功能的加持下,我們可以僅靠 StpUtil.login(id) 一句代碼就完成登錄認(rèn)證。
除了登錄方法,我們還需要:
// 當(dāng)前會(huì)話注銷登錄
StpUtil.logout();
// 獲取當(dāng)前會(huì)話是否已經(jīng)登錄,返回true=已登錄,false=未登錄
StpUtil.isLogin();
// 檢驗(yàn)當(dāng)前會(huì)話是否已經(jīng)登錄, 如果未登錄,則拋出異常:`NotLoginException`
StpUtil.checkLogin();異常 NotLoginException 代表當(dāng)前會(huì)話暫未登錄,可能的原因有很多:前端沒(méi)有提交 Token、前端提交的 Token 是無(wú)效的、前端提交的 Token 已經(jīng)過(guò)期 …… 等等,可參照此篇:未登錄場(chǎng)景值,了解如何獲取未登錄的場(chǎng)景值。
會(huì)話查詢
// 獲取當(dāng)前會(huì)話賬號(hào)id, 如果未登錄,則拋出異常:`NotLoginException`
StpUtil.getLoginId();
// 類似查詢API還有:
StpUtil.getLoginIdAsString(); // 獲取當(dāng)前會(huì)話賬號(hào)id, 并轉(zhuǎn)化為`String`類型
StpUtil.getLoginIdAsInt(); // 獲取當(dāng)前會(huì)話賬號(hào)id, 并轉(zhuǎn)化為`int`類型
StpUtil.getLoginIdAsLong(); // 獲取當(dāng)前會(huì)話賬號(hào)id, 并轉(zhuǎn)化為`long`類型
// ---------- 指定未登錄情形下返回的默認(rèn)值 ----------
// 獲取當(dāng)前會(huì)話賬號(hào)id, 如果未登錄,則返回null
StpUtil.getLoginIdDefaultNull();
// 獲取當(dāng)前會(huì)話賬號(hào)id, 如果未登錄,則返回默認(rèn)值 (`defaultValue`可以為任意類型)
StpUtil.getLoginId(T defaultValue);Token 查詢
// 獲取當(dāng)前會(huì)話的token值
StpUtil.getTokenValue();
// 獲取當(dāng)前`StpLogic`的token名稱
StpUtil.getTokenName();
// 獲取指定token對(duì)應(yīng)的賬號(hào)id,如果未登錄,則返回 null
StpUtil.getLoginIdByToken(String tokenValue);
// 獲取當(dāng)前會(huì)話剩余有效期(單位:s,返回-1代表永久有效)
StpUtil.getTokenTimeout();
// 獲取當(dāng)前會(huì)話的token信息參數(shù)
StpUtil.getTokenInfo();有關(guān)TokenInfo參數(shù)詳解,請(qǐng)參考:TokenInfo參數(shù)詳解
來(lái)個(gè)小測(cè)試,加深一下理解
新建 LoginController,復(fù)制以下代碼
/**
* 登錄測(cè)試
*/
@RestController
@RequestMapping("/acc/")
public class LoginController {
// 測(cè)試登錄 ---- http://localhost:8081/acc/doLogin?name=zhang&pwd=123456
@RequestMapping("doLogin")
public SaResult doLogin(String name, String pwd) {
// 此處僅作模擬示例,真實(shí)項(xiàng)目需要從數(shù)據(jù)庫(kù)中查詢數(shù)據(jù)進(jìn)行比對(duì)
if("iron".equals(name) && "123456".equals(pwd)) {
StpUtil.login(10001);
return SaResult.ok("登錄成功");
}
return SaResult.error("登錄失敗");
}
// 查詢登錄狀態(tài) ---- http://localhost:8081/acc/isLogin
@RequestMapping("isLogin")
public SaResult isLogin() {
return SaResult.ok("是否登錄:" + StpUtil.isLogin());
}
// 查詢 Token 信息 ---- http://localhost:8081/acc/tokenInfo
@RequestMapping("tokenInfo")
public SaResult tokenInfo() {
return SaResult.data(StpUtil.getTokenInfo());
}
// 測(cè)試注銷 ---- http://localhost:8081/acc/logout
@RequestMapping("logout")
public SaResult logout() {
StpUtil.logout();
return SaResult.ok();
}
}權(quán)限認(rèn)證
設(shè)計(jì)思路
所謂權(quán)限認(rèn)證,核心邏輯就是判斷一個(gè)賬號(hào)是否擁有指定權(quán)限:
- 有,就讓你通過(guò)。
- 沒(méi)有?那么禁止訪問(wèn)!
深入到底層數(shù)據(jù)中,就是每個(gè)賬號(hào)都會(huì)擁有一個(gè)權(quán)限碼集合,框架來(lái)校驗(yàn)這個(gè)集合中是否包含指定的權(quán)限碼。
例如:當(dāng)前賬號(hào)擁有權(quán)限碼集合 ["user-add", "user-delete", "user-get"],這時(shí)候我來(lái)校驗(yàn)權(quán)限 "user-update",則其結(jié)果就是:驗(yàn)證失敗,禁止訪問(wèn)。
所以現(xiàn)在問(wèn)題的核心就是:
- 如何獲取一個(gè)賬號(hào)所擁有的的權(quán)限碼集合?
- 本次操作需要驗(yàn)證的權(quán)限碼是哪個(gè)?
獲取當(dāng)前賬號(hào)權(quán)限碼集合
因?yàn)槊總€(gè)項(xiàng)目的需求不同,其權(quán)限設(shè)計(jì)也千變?nèi)f化,因此 [ 獲取當(dāng)前賬號(hào)權(quán)限碼集合 ] 這一操作不可能內(nèi)置到框架中, 所以 Sa-Token 將此操作以接口的方式暴露給你,以方便你根據(jù)自己的業(yè)務(wù)邏輯進(jìn)行重寫。
你需要做的就是新建一個(gè)類,實(shí)現(xiàn) StpInterface接口,例如以下代碼:
/**
* 自定義權(quán)限驗(yàn)證接口擴(kuò)展
*/
@Component // 保證此類被SpringBoot掃描,完成Sa-Token的自定義權(quán)限驗(yàn)證擴(kuò)展
public class StpInterfaceImpl implements StpInterface {
/**
* 返回一個(gè)賬號(hào)所擁有的權(quán)限碼集合
*/
@Override
public List getPermissionList(Object loginId, String loginType) {
// 本list僅做模擬,實(shí)際項(xiàng)目中要根據(jù)具體業(yè)務(wù)邏輯來(lái)查詢權(quán)限
List list = new ArrayList();
list.add("101");
list.add("user.add");
list.add("user.update");
list.add("user.get");
// list.add("user.delete");
list.add("art.*");
return list;
}
/**
* 返回一個(gè)賬號(hào)所擁有的角色標(biāo)識(shí)集合 (權(quán)限與角色可分開校驗(yàn))
*/
@Override
public List getRoleList(Object loginId, String loginType) {
// 本list僅做模擬,實(shí)際項(xiàng)目中要根據(jù)具體業(yè)務(wù)邏輯來(lái)查詢角色
List list = new ArrayList();
list.add("admin");
list.add("super-admin");
return list;
}
} 參數(shù)解釋:
- loginId:賬號(hào)id,即你在調(diào)用 StpUtil.login(id) 時(shí)寫入的標(biāo)識(shí)值。
- loginType:賬號(hào)體系標(biāo)識(shí),此處可以暫時(shí)忽略,在 [ 多賬戶認(rèn)證 ] 章節(jié)下會(huì)對(duì)這個(gè)概念做詳細(xì)的解釋。
可參考代碼:碼云:StpInterfaceImpl.java
注意: StpInterface 接口在需要鑒權(quán)時(shí)由框架自動(dòng)調(diào)用,開發(fā)者只需要配置好就可以使用下面的鑒權(quán)方法或后面的注解鑒權(quán)
權(quán)限校驗(yàn)
然后就可以用以下api來(lái)鑒權(quán)了
// 獲?。寒?dāng)前賬號(hào)所擁有的權(quán)限集合
StpUtil.getPermissionList();
// 判斷:當(dāng)前賬號(hào)是否含有指定權(quán)限, 返回 true 或 false
StpUtil.hasPermission("user.add");
// 校驗(yàn):當(dāng)前賬號(hào)是否含有指定權(quán)限, 如果驗(yàn)證未通過(guò),則拋出異常: NotPermissionException
StpUtil.checkPermission("user.add");
// 校驗(yàn):當(dāng)前賬號(hào)是否含有指定權(quán)限 [指定多個(gè),必須全部驗(yàn)證通過(guò)]
StpUtil.checkPermissionAnd("user.add", "user.delete", "user.get");
// 校驗(yàn):當(dāng)前賬號(hào)是否含有指定權(quán)限 [指定多個(gè),只要其一驗(yàn)證通過(guò)即可]
StpUtil.checkPermissionOr("user.add", "user.delete", "user.get");擴(kuò)展:NotPermissionException 對(duì)象可通過(guò) getLoginType() 方法獲取具體是哪個(gè) StpLogic 拋出的異常
角色校驗(yàn)
在Sa-Token中,角色和權(quán)限可以獨(dú)立驗(yàn)證
// 獲?。寒?dāng)前賬號(hào)所擁有的角色集合
StpUtil.getRoleList();
// 判斷:當(dāng)前賬號(hào)是否擁有指定角色, 返回 true 或 false
StpUtil.hasRole("super-admin");
// 校驗(yàn):當(dāng)前賬號(hào)是否含有指定角色標(biāo)識(shí), 如果驗(yàn)證未通過(guò),則拋出異常: NotRoleException
StpUtil.checkRole("super-admin");
// 校驗(yàn):當(dāng)前賬號(hào)是否含有指定角色標(biāo)識(shí) [指定多個(gè),必須全部驗(yàn)證通過(guò)]
StpUtil.checkRoleAnd("super-admin", "shop-admin");
// 校驗(yàn):當(dāng)前賬號(hào)是否含有指定角色標(biāo)識(shí) [指定多個(gè),只要其一驗(yàn)證通過(guò)即可]
StpUtil.checkRoleOr("super-admin", "shop-admin");擴(kuò)展:NotRoleException 對(duì)象可通過(guò) getLoginType() 方法獲取具體是哪個(gè) StpLogic 拋出的異常
權(quán)限通配符
Sa-Token允許你根據(jù)通配符指定泛權(quán)限,例如當(dāng)一個(gè)賬號(hào)擁有art.*的權(quán)限時(shí),art.add、art.delete、art.update都將匹配通過(guò)
// 當(dāng)擁有 art.* 權(quán)限時(shí)
StpUtil.hasPermission("art.add"); // true
StpUtil.hasPermission("art.update"); // true
StpUtil.hasPermission("goods.add"); // false
// 當(dāng)擁有 *.delete 權(quán)限時(shí)
StpUtil.hasPermission("art.delete"); // true
StpUtil.hasPermission("user.delete"); // true
StpUtil.hasPermission("user.update"); // false
// 當(dāng)擁有 *.js 權(quán)限時(shí)
StpUtil.hasPermission("index.js"); // true
StpUtil.hasPermission("index.css"); // false
StpUtil.hasPermission("index.html"); // false上帝權(quán)限:當(dāng)一個(gè)賬號(hào)擁有 "*" 權(quán)限時(shí),他可以驗(yàn)證通過(guò)任何權(quán)限碼 (角色認(rèn)證同理)
如何把權(quán)限精確到按鈕級(jí)?
權(quán)限精確到按鈕級(jí)的意思就是指:權(quán)限范圍可以控制到頁(yè)面上的每一個(gè)按鈕是否顯示。
思路:如此精確的范圍控制只依賴后端已經(jīng)難以完成,此時(shí)需要前端進(jìn)行一定的邏輯判斷。
如果是前后端一體項(xiàng)目,可以參考:Thymeleaf 標(biāo)簽方言,如果是前后端分離項(xiàng)目,則:
- 在登錄時(shí),把當(dāng)前賬號(hào)擁有的所有權(quán)限碼一次性返回給前端。
- 前端將權(quán)限碼集合保存在localStorage或其它全局狀態(tài)管理對(duì)象中。
- 在需要權(quán)限控制的按鈕上,使用 js 進(jìn)行邏輯判斷,例如在Vue框架中我們可以使用如下寫法:
其中:arr是當(dāng)前用戶擁有的權(quán)限碼數(shù)組,user.delete是顯示按鈕需要擁有
本文名稱:再見,Shiro!你好,Sa-Token!
URL網(wǎng)址:http://fisionsoft.com.cn/article/djeossd.html


咨詢
建站咨詢
