Spring Security太復(fù)雜?試試這個(gè)輕量、強(qiáng)大、優(yōu)雅的權(quán)限認(rèn)證框架!

各位程序猿小伙伴們,中秋快樂~在節(jié)日歡快的氣氛中大家是不是還在奮筆疾書、沉浸在學(xué)習(xí)的海洋中呢?
小編這兩天休息在家一直在想一個(gè)問題,那就是我們在開發(fā)SpringBoot項(xiàng)目的時(shí)候,該怎么做好權(quán)限認(rèn)證呢?之前有和小伙伴討論的時(shí)候說起過一些常見的相關(guān)框架,例如Shiro或者Spring Security等,但這些框架似乎在運(yùn)用上存在著各種美中不足的地方,尤其是用起來太過復(fù)雜,勸退了不少新手程序猿,讓人總覺意猶未盡。
不過呢,就在這個(gè)假期里,小編發(fā)現(xiàn)了一個(gè)新的權(quán)限認(rèn)證框架,總體感覺使用起來簡單明了,整體的API設(shè)計(jì)呢也屬上乘,所以趕緊來和大家分享下~
他就是,權(quán)限認(rèn)證框架領(lǐng)域一塊璀璨的明珠~~~下面讓我們有請:
Sa-Token

Sa-Token,可能是史上功能最全的Java權(quán)限認(rèn)證框架之一!或者可以去掉之一兩字。
截止目前為止,Sa-Token已集成——登錄認(rèn)證、權(quán)限認(rèn)證、分布式Session會(huì)話、微服務(wù)網(wǎng)關(guān)鑒權(quán)、單點(diǎn)登錄、OAuth2.0、踢人下線、Redis集成、前后臺分離、記住我模式、模擬他人賬號、臨時(shí)身份切換、賬號封禁、多賬號認(rèn)證體系、注解式鑒權(quán)、路由攔截式鑒權(quán)、花式token生成、自動(dòng)續(xù)簽、同端互斥登錄、會(huì)話治理、密碼加密、jwt集成、Spring集成、WebFlux集成等等等等各種各樣的豐富內(nèi)容。
看著這么多功能似乎有種讓人眼花的感覺,沒事沒事,濃縮一下精華,其實(shí)你只要記?。?/p>
Sa-Token 作為一個(gè)輕量級 Java 權(quán)限認(rèn)證框架,主要解決:登錄認(rèn)證、權(quán)限認(rèn)證、Session會(huì)話、單點(diǎn)登錄、OAuth2.0、微服務(wù)網(wǎng)關(guān)鑒權(quán) 等一系列權(quán)限相關(guān)問題。
Sa-Token的一大優(yōu)點(diǎn)就是API設(shè)計(jì)簡單不冗余復(fù)雜。有多簡單?可能光說不夠直觀,小編帶你看下他的登錄認(rèn)證:
// 在登錄時(shí)寫入當(dāng)前會(huì)話的賬號id
StpUtil.login(10001);
// 然后在需要校驗(yàn)登錄處調(diào)用以下方法:
// 如果當(dāng)前會(huì)話未登錄,這句代碼會(huì)拋出 `NotLoginException` 異常
StpUtil.checkLogin();
就上面短短的兩句話,我們已經(jīng)完成了登錄認(rèn)證。用過其他框架的小伙伴可能現(xiàn)在滿腦在都是問號,什么?自定義 Realm 呢?全局過濾器呢?各種配置文件嗎?
是的,相對于前文提到的Shiro、Spring Security, Sa-Token就是如此的簡單便捷,更加適合當(dāng)今時(shí)代的潮流與效率至上。
小編再舉兩個(gè)例子,例如權(quán)限認(rèn)證:
(只有具備 user:add 權(quán)限的會(huì)話才可以進(jìn)入請求)
@SaCheckPermission("user:add")
@RequestMapping("/user/insert")
public String insert(SysUser user) {
// ...
return "用戶增加";
}
又例如賬號登出:
將某個(gè)賬號踢下線(待到對方再次訪問系統(tǒng)時(shí)會(huì)拋出NotLoginException異常)
// 使賬號id為 10001 的會(huì)話強(qiáng)制注銷登錄
StpUtil.logoutByLoginId(10001);
不止以上這些功能,其實(shí)在Sa-Token里,絕大多數(shù)功能都可以只用一行代碼完成,聽著很神奇是吧?但事實(shí)就是這樣:
StpUtil.login(10001); // 標(biāo)記當(dāng)前會(huì)話登錄的賬號id
StpUtil.getLoginId(); // 獲取當(dāng)前會(huì)話登錄的賬號id
StpUtil.isLogin(); // 獲取當(dāng)前會(huì)話是否已經(jīng)登錄, 返回true或false
StpUtil.logout(); // 當(dāng)前會(huì)話注銷登錄
StpUtil.logoutByLoginId(10001); // 讓賬號為10001的會(huì)話注銷登錄(踢人下線)
StpUtil.hasRole("super-admin"); // 查詢當(dāng)前賬號是否含有指定角色標(biāo)識, 返回true或false
StpUtil.hasPermission("user:add"); // 查詢當(dāng)前賬號是否含有指定權(quán)限, 返回true或false
StpUtil.getSession(); // 獲取當(dāng)前賬號id的Session
StpUtil.getSessionByLoginId(10001); // 獲取賬號id為10001的Session
StpUtil.getTokenValueByLoginId(10001); // 獲取賬號id為10001的token令牌值
StpUtil.login(10001, "PC"); // 指定設(shè)備標(biāo)識登錄,常用于“同端互斥登錄”
StpUtil.logoutByLoginId(10001, "PC"); // 指定設(shè)備標(biāo)識進(jìn)行強(qiáng)制注銷 (不同端不受影響)
StpUtil.openSafe(120); // 在當(dāng)前會(huì)話開啟二級認(rèn)證,有效期為120秒
StpUtil.checkSafe(); // 校驗(yàn)當(dāng)前會(huì)話是否處于二級認(rèn)證有效期內(nèi),校驗(yàn)失敗會(huì)拋出異常
StpUtil.switchTo(10044); // 將當(dāng)前會(huì)話身份臨時(shí)切換為其它賬號
有小伙伴可能要問了,那么這么簡單好用的Sa-Token到底支持哪些功能???其實(shí)就是前文看著暈乎乎那一堆功能,不過如果小編給你整理一下,你就會(huì)覺得清晰無比:
功能一覽
登錄認(rèn)證 —— 單端登錄、多端登錄、同端互斥登錄、七天內(nèi)免登錄 權(quán)限認(rèn)證 —— 權(quán)限認(rèn)證、角色認(rèn)證、會(huì)話二級認(rèn)證 Session會(huì)話 —— 全端共享Session、單端獨(dú)享Session、自定義Session 踢人下線 —— 根據(jù)賬號id踢人下線、根據(jù)Token值踢人下線 賬號封禁 —— 指定天數(shù)封禁、永久封禁、設(shè)定解封時(shí)間 持久層擴(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)登錄模式:無論是否跨域、是否共享Redis,都可以搞定 OAuth2.0認(rèn)證 —— 基于RFC-6749標(biāo)準(zhǔn)編寫,OAuth2.0標(biāo)準(zhǔn)流程的授權(quán)認(rèn)證,支持openid模式 二級認(rèn)證 —— 在已登錄的基礎(chǔ)上再次認(rèn)證,保證安全性 Basic認(rèn)證 —— 一行代碼接入 Http Basic 認(rèn)證 獨(dú)立Redis —— 將權(quán)限緩存與業(yè)務(wù)緩存分離 臨時(shí)Token驗(yàn)證 —— 解決短時(shí)間的Token授權(quán)問題 模擬他人賬號 —— 實(shí)時(shí)操作任意用戶狀態(tài)數(shù)據(jù) 臨時(shí)身份切換 —— 將會(huì)話身份臨時(shí)切換為其它賬號 前后臺分離 —— APP、小程序等不支持Cookie的終端 同端互斥登錄 —— 像QQ一樣手機(jī)電腦同時(shí)在線,但是兩個(gè)手機(jī)上互斥登錄 多賬號認(rèn)證體系 —— 比如一個(gè)商城項(xiàng)目的user表和admin表分開鑒權(quán) 花式token生成 —— 內(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過期策略,靈活搭配使用,還可自動(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集成包,真正的開箱即用



功能結(jié)構(gòu)


項(xiàng)目目錄結(jié)構(gòu):
── sa-token
├── sa-token-core // [核心] Sa-Token 核心模塊
├── sa-token-starter // [整合] Sa-Token 與其它框架整合
├── sa-token-servlet // [整合] Sa-Token 整合 Servlet容器實(shí)現(xiàn)類包
├── sa-token-spring-boot-starter // [整合] Sa-Token 整合 SpringBoot 快速集成
├── sa-token-reactor-spring-boot-starter // [整合] Sa-Token 整合 Reactor響應(yīng)式編程 快速集成
├── sa-token-solon-plugin // [整合] Sa-Token 整合 Solon 快速集成
├── sa-token-plugin // [插件] Sa-Token 插件合集
├── sa-token-dao-redis // [插件] Sa-Token 整合 Redis (使用jdk默認(rèn)序列化方式)
├── sa-token-dao-redis-jackson // [插件] Sa-Token 整合 Redis (使用jackson序列化方式)
├── sa-token-spring-aop // [插件] Sa-Token 整合 SpringAOP 注解鑒權(quán)
├── sa-token-temp-jwt // [插件] Sa-Token 整合 jwt 臨時(shí)令牌鑒權(quán)
├── sa-token-quick-login // [插件] Sa-Token 快速注入登錄頁插件
├── sa-token-alone-redis // [插件] Sa-Token 獨(dú)立Redis插件,實(shí)現(xiàn)[權(quán)限緩存與業(yè)務(wù)緩存分離]
├── sa-token-oauth2 // [插件] Sa-Token 實(shí)現(xiàn) OAuth2.0 模塊
├── sa-token-demo // [示例] Sa-Token 示例合集
├── sa-token-demo-springboot // [示例] Sa-Token 整合 SpringBoot
├── sa-token-demo-webflux // [示例] Sa-Token 整合 WebFlux
├── sa-token-demo-jwt // [示例] Sa-Token 集成 jwt
├── sa-token-demo-solon // [示例] Sa-Token 集成 Solon
├── sa-token-demo-quick-login // [示例] Sa-Token 集成 quick-login 模塊
├── sa-token-demo-alone-redis // [示例] Sa-Token 集成 alone-redis 模塊
├── sa-token-demo-sso1 // [示例] Sa-Token 集成 SSO單點(diǎn)登錄-模式一簡單測試
├── sa-token-demo-sso1-server // [示例] Sa-Token 集成 SSO單點(diǎn)登錄-模式一 認(rèn)證中心
├── sa-token-demo-sso1-client // [示例] Sa-Token 集成 SSO單點(diǎn)登錄-模式一 應(yīng)用端
├── sa-token-demo-sso2-server // [示例] Sa-Token 集成 SSO單點(diǎn)登錄-模式二 認(rèn)證中心
├── sa-token-demo-sso2-client-h5 // [示例] Sa-Token 集成 SSO單點(diǎn)登錄-模式二 應(yīng)用端
├── sa-token-demo-sso2-server // [示例] Sa-Token 集成 SSO單點(diǎn)登錄-模式二 認(rèn)證中心 (前后端分離)
├── sa-token-demo-sso2-client-h5 // [示例] Sa-Token 集成 SSO單點(diǎn)登錄-模式二 應(yīng)用端 (前后端分離)
├── sa-token-demo-sso3-server // [示例] Sa-Token 集成 SSO單點(diǎn)登錄-模式三 認(rèn)證中心
├── sa-token-demo-sso3-client // [示例] Sa-Token 集成 SSO單點(diǎn)登錄-模式三 應(yīng)用端
├── sa-token-demo-oauth2-server // [示例] Sa-Token 集成 OAuth2.0 (服務(wù)端)
├── sa-token-demo-oauth2-client // [示例] Sa-Token 集成 OAuth2.0 (客戶端)
├── sa-token-doc // [文檔] Sa-Token 開發(fā)文檔
├──pom.xml // [依賴] 頂級pom文件
可能又有小伙伴會(huì)問,這么好用?引用集成起來難嗎?當(dāng)然也是非常簡單的。
引用依賴
在項(xiàng)目中直接通過 pom.xml 引入依賴即可
<!-- Sa-Token 權(quán)限認(rèn)證 -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
<version>1.26.0</version>
</dependency>
然后在application.yml中增加如下配置,就可以使用框架啦:
server:
# 端口
port: 8081
# Sa-Token配置
sa-token:
# token名稱 (同時(shí)也是cookie名稱)
token-name: satoken
# token有效期,單位s 默認(rèn)30天, -1代表永不過期
timeout: 2592000
# token臨時(shí)有效期 (指定時(shí)間內(nèi)無操作就視為token過期) 單位: 秒
activity-timeout: -1
# 是否允許同一賬號并發(fā)登錄 (為true時(shí)允許一起登錄, 為false時(shí)新登錄擠掉舊登錄)
is-concurrent: true
# 在多人登錄同一賬號時(shí),是否共用一個(gè)token (為true時(shí)所有登錄共用一個(gè)token, 為false時(shí)每次登錄新建一個(gè)token)
is-share: false
# token風(fēng)格
token-style: uuid
# 是否輸出操作日志
is-log: false
嘗試運(yùn)行
新建包 com.pj ,在此包內(nèi)新建主類 SaTokenDemoApplication.java,輸入以下代碼:
@SpringBootApplication
public class SaTokenDemoApplication {
public static void main(String[] args) throws JsonProcessingException {
SpringApplication.run(SaTokenDemoApplication.class, args);
System.out.println("啟動(dòng)成功:Sa-Token配置如下:" + SaManager.getConfig());
}
}
再創(chuàng)建一個(gè)測試類
@RestController
@RequestMapping("/user/")
public class UserController {
// 測試登錄,瀏覽器訪問:http://localhost:8081/user/doLogin?username=zhang&password=123456
@RequestMapping("doLogin")
public String doLogin(String username, String password) {
// 此處僅作模擬示例,真實(shí)項(xiàng)目需要從數(shù)據(jù)庫中查詢數(shù)據(jù)進(jìn)行比對
if("zhang".equals(username) && "123456".equals(password)) {
StpUtil.login(10001);
return "登錄成功";
}
return "登錄失敗";
}
// 查詢登錄狀態(tài),瀏覽器訪問:http://localhost:8081/user/isLogin
@RequestMapping("isLogin")
public String isLogin() {
return "當(dāng)前會(huì)話是否登錄:" + StpUtil.isLogin();
}
}
嘗試運(yùn)行,啟動(dòng)代碼,從瀏覽器依次訪問下面這些測試接口就可以了:

是不是有點(diǎn)感覺了?Sa-Token 還提供了詳細(xì)的線上指導(dǎo)文檔,絕對手把手教你學(xué)會(huì)使用這個(gè)框架。不會(huì)用的情況,絕對是不存在的~
想必小伙伴們都已經(jīng)迫不及待想試試這個(gè)看似神奇又簡單易用的框架了,那么趕緊關(guān)注小編,一起來獲取項(xiàng)目及線上文檔地址吧:
點(diǎn)擊下方卡片,關(guān)注公眾號“TJ君”
回復(fù)“權(quán)限控制”,獲取倉庫及文檔地址
