SpringBoot權(quán)限認(rèn)證-Sa-Token的使用詳解
本文詳細(xì)介紹了Sa-Token在Java項(xiàng)目中的使用方法,包括Sa-Token的基本概念、與其他權(quán)限框架的比較、基本語法和高級(jí)用法,并通過實(shí)例講解了如何在項(xiàng)目中集成和使用Sa-Token。作為一款輕量級(jí)Java權(quán)限認(rèn)證框架,Sa-Token在簡(jiǎn)化權(quán)限管理、提高開發(fā)效率方面發(fā)揮了重要作用。本文還將深入探討Sa-Token的核心原理,通過內(nèi)部代碼展示其工作機(jī)制。最后,總結(jié)了Sa-Token的優(yōu)缺點(diǎn)及其在實(shí)際開發(fā)中的應(yīng)用場(chǎng)景,為開發(fā)者提供全面的指導(dǎo)。
一、Sa-Token介紹
1. Sa-Token簡(jiǎn)介
Sa-Token是一款輕量級(jí)Java權(quán)限認(rèn)證框架,旨在解決Web系統(tǒng)中常見的登錄認(rèn)證、權(quán)限驗(yàn)證、Session會(huì)話、單點(diǎn)登錄等問題。其核心目標(biāo)是以最簡(jiǎn)潔的方式,實(shí)現(xiàn)強(qiáng)大的權(quán)限控制功能,幫助開發(fā)者快速完成權(quán)限系統(tǒng)的搭建。
Sa-Token具有如下優(yōu)勢(shì):
| 優(yōu)勢(shì) | 描述 |
|---|---|
| 簡(jiǎn)單易用 | API設(shè)計(jì)簡(jiǎn)潔明了,易于集成和使用,上手快,學(xué)習(xí)成本低。 |
| 功能豐富 | 支持多種權(quán)限控制需求,滿足復(fù)雜業(yè)務(wù)場(chǎng)景。支持登錄認(rèn)證、權(quán)限驗(yàn)證、角色驗(yàn)證、Session會(huì)話、多賬號(hào)體系等功能。 |
| 高性能 | 輕量級(jí)設(shè)計(jì),對(duì)系統(tǒng)性能影響小。 |
| 高度可擴(kuò)展 | 提供豐富的擴(kuò)展接口,與Spring、Spring Boot等常用框架高度兼容,支持自定義持久化、注解方式驗(yàn)證、單點(diǎn)登錄等高級(jí)特性。 |
| 社區(qū)活躍 | 有良好的社區(qū)支持和文檔資源。 |
2. Sa-Token原理解析
Sa-Token的核心原理是通過Token機(jī)制實(shí)現(xiàn)用戶的身份認(rèn)證和權(quán)限校驗(yàn)。
其主要工作流程如下:
① 登錄認(rèn)證:用戶登錄成功后,服務(wù)器生成一個(gè)全局唯一的Token,并將其返回給客戶端。
② Token存儲(chǔ):Token與用戶身份信息的映射關(guān)系保存在服務(wù)器的會(huì)話中(如Redis、內(nèi)存等)。
③ 權(quán)限驗(yàn)證:客戶端請(qǐng)求時(shí)攜帶Token,服務(wù)器根據(jù)Token獲取用戶信息,驗(yàn)證其權(quán)限是否滿足要求。
④ 會(huì)話管理:支持Session會(huì)話管理,可以獲取和操作當(dāng)前會(huì)話的屬性。
流程圖例如下:

3. Sa-Token與其他權(quán)限框架比較
Sa-Token與其他常見權(quán)限框架在學(xué)習(xí)成本、集成難度上有顯著優(yōu)勢(shì):
| 特性 | Sa-Token | Shiro | Spring Security |
|---|---|---|---|
| 學(xué)習(xí)成本 | 低 | 中 | 高 |
| 功能豐富度 | 高 | 中 | 高 |
| 集成難度 | 低 | 中 | 高 |
| 性能表現(xiàn) | 高 | 中 | 中 |
| 社區(qū)支持 | 活躍 | 一般 | 活躍 |
| 擴(kuò)展性 | 高 | 中 | 高 |
二、Sa-Token的基本語法
在實(shí)際項(xiàng)目中,Sa-Token通過簡(jiǎn)單的配置和API調(diào)用,即可實(shí)現(xiàn)完整的權(quán)限管理功能。以下將通過一個(gè)完整的Spring Boot示例,演示如何集成和使用Sa-Token。
1. 創(chuàng)建Spring Boot項(xiàng)目
首先,創(chuàng)建一個(gè)新的Spring Boot項(xiàng)目,可以使用IDEA的項(xiàng)目向?qū)Щ騍pring Initializr。
引入必要的依賴:
<dependencies>
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Sa-Token核心依賴 -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
<version>1.34.0</version>
</dependency>
</dependencies>2. 配置Sa-Token
application.yml
# Sa-Token配置,可根據(jù)需要進(jìn)行調(diào)整 sa-token: # token有效期,單位秒,默認(rèn)30天 timeout: 2592000 # 是否打開二級(jí)登錄校驗(yàn) open-safe: false
3. 配置攔截器
創(chuàng)建配置類,添加Sa-Token的攔截器,以攔截請(qǐng)求并進(jìn)行權(quán)限驗(yàn)證。
SaTokenConfigure.java
import cn.dev33.satoken.interceptor.SaAnnotationInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;
@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注冊(cè)Sa-Token的注解攔截器,攔截所有路徑
registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**");
}
}4. 登錄認(rèn)證
創(chuàng)建登錄接口,實(shí)現(xiàn)用戶登錄功能。
LoginController.java
import cn.dev33.satoken.stp.StpUtil;
import org.springframework.web.bind.annotation.*;
@RestController
public class LoginController {
@PostMapping("/login")
public String login(@RequestParam String username, @RequestParam String password) {
// 1. 校驗(yàn)用戶名和密碼(這里模擬一個(gè)簡(jiǎn)單的校驗(yàn))
if("admin".equals(username) && "123456".equals(password)) {
// 2. 登錄,保存用戶ID為10001
StpUtil.login(10001);
return "登錄成功,Token:" + StpUtil.getTokenValue();
}
return "用戶名或密碼錯(cuò)誤";
}
}說明:
- 調(diào)用
StpUtil.login(10001)方法,實(shí)現(xiàn)登錄操作,參數(shù)為用戶的唯一標(biāo)識(shí)ID。 - 登錄成功后,可以通過
StpUtil.getTokenValue()獲取當(dāng)前會(huì)話的Token。
5. 權(quán)限驗(yàn)證
創(chuàng)建需要權(quán)限驗(yàn)證的接口,例如獲取用戶信息的接口。
UserController.java
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/user")
public class UserController {
// 查詢用戶信息,需登錄
@GetMapping("/info")
public String getUserInfo() {
// 校驗(yàn)是否登錄
StpUtil.checkLogin();
// 獲取用戶ID
int userId = StpUtil.getLoginIdAsInt();
return "當(dāng)前用戶信息,ID:" + userId;
}
// 修改用戶信息,需有權(quán)限"user:update"
@SaCheckPermission("user:update")
@PostMapping("/update")
public String updateUser() {
return "用戶信息更新成功";
}
}說明:
- 使用
StpUtil.checkLogin()方法手動(dòng)校驗(yàn)登錄狀態(tài)。 - 使用
@SaCheckPermission("user:update")注解,聲明該接口需要權(quán)限user:update。
6. 角色驗(yàn)證
如果需要基于角色進(jìn)行權(quán)限控制,可以使用@SaCheckRole注解。
import cn.dev33.satoken.annotation.SaCheckRole;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/admin")
public class AdminController {
// 僅管理員角色可訪問
@SaCheckRole("admin")
@GetMapping("/dashboard")
public String adminDashboard() {
return "歡迎進(jìn)入管理員控制臺(tái)";
}
}7. 自定義權(quán)限驗(yàn)證邏輯
需要自定義獲取用戶權(quán)限和角色的邏輯,可以實(shí)現(xiàn)StpInterface接口。
StpInterfaceImpl.java
import cn.dev33.satoken.stp.StpInterface;
import org.springframework.stereotype.Component;
import java.util.*;
@Component
public class StpInterfaceImpl implements StpInterface {
// 返回一個(gè)用戶所擁有的權(quán)限碼集合
@Override
public List<String> getPermissionList(Object loginId, String loginKey) {
// 模擬從數(shù)據(jù)庫(kù)獲取權(quán)限
List<String> permissionList = new ArrayList<>();
if("10001".equals(loginId.toString())) {
permissionList.add("user:update");
permissionList.add("user:delete");
}
return permissionList;
}
// 返回一個(gè)用戶所擁有的角色標(biāo)識(shí)集合 (權(quán)限與角色可分開校驗(yàn))
@Override
public List<String> getRoleList(Object loginId, String loginKey) {
// 模擬從數(shù)據(jù)庫(kù)獲取角色
List<String> roleList = new ArrayList<>();
if("10001".equals(loginId.toString())) {
roleList.add("admin");
}
return roleList;
}
}說明:
- 實(shí)現(xiàn)
getPermissionList方法,返回指定用戶的權(quán)限列表。 - 實(shí)現(xiàn)
getRoleList方法,返回指定用戶的角色列表。
8. 會(huì)話管理
Sa-Token提供了會(huì)話管理功能,可以在Session中存儲(chǔ)和獲取數(shù)據(jù)。
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpUtil;
public void sessionDemo() {
// 獲取當(dāng)前會(huì)話的Session
SaSession session = StpUtil.getSession();
// 存儲(chǔ)數(shù)據(jù)
session.set("name", "張三");
session.set("email", "zhangsan@example.com");
// 獲取數(shù)據(jù)
String name = session.getString("name");
String email = session.getString("email");
// 輸出
System.out.println("姓名:" + name);
System.out.println("郵箱:" + email);
}9. 踢人下線
可以通過用戶ID強(qiáng)制用戶下線。
// 將用戶ID為10001的用戶踢下線
StpUtil.logoutByLoginId(10001);
// 檢查用戶是否已被踢下線
boolean isLogout = StpUtil.isLogin();
System.out.println("用戶是否登錄:" + isLogout);10. 注銷登錄
用戶主動(dòng)注銷登錄,可以調(diào)用StpUtil.logout()方法。
// 注銷登錄
StpUtil.logout();
// 檢查登錄狀態(tài)
boolean isLogin = StpUtil.isLogin();
System.out.println("用戶是否登錄:" + isLogin);三、Sa-Token的高級(jí)用法
1. 自定義持久化
Sa-Token默認(rèn)使用內(nèi)存來存儲(chǔ)Token信息,在分布式環(huán)境中,可以使用Redis作為持久化介質(zhì)。
引入Redis依賴:
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-dao-redis</artifactId>
<version>1.34.0</version>
</dependency>配置Redis持久化:
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.dao.SaTokenDaoRedis;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SaTokenDaoConfig {
@Bean
public SaTokenDao saTokenDao() {
// 返回Redis實(shí)現(xiàn)
return new SaTokenDaoRedis();
}
}配置Redis連接信息:
application.yml
# 配置Redis連接信息
spring:
redis:
host: localhost
port: 6379
password:2. 單點(diǎn)登錄(SSO)
Sa-Token提供了SSO模塊,可以快速實(shí)現(xiàn)單點(diǎn)登錄功能。
引入SSO依賴:
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-sso</artifactId>
<version>1.34.0</version>
</dependency>配置SSO相關(guān)參數(shù):
application.yml
# SSO單點(diǎn)登錄配置
sa-token:
sso:
mode: client
server-url: http://sso-server.com
client-url: http://client1.com**實(shí)現(xiàn)SSO登錄邏輯:**
在客戶端應(yīng)用中,配置SSO的攔截器,自動(dòng)處理單點(diǎn)登錄。
**SaTokenConfigure.java**
```java
import cn.dev33.satoken.sso.SaSsoHandle;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;
@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注冊(cè)SSO攔截器
registry.addInterceptor(new SaSsoHandle()).addPathPatterns("/**");
}
}3. OAuth2.0支持
Sa-Token也支持OAuth2.0協(xié)議,可以實(shí)現(xiàn)與第三方平臺(tái)的對(duì)接。
引入OAuth2.0依賴:
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-oauth2</artifactId>
<version>1.34.0</version>
</dependency>配置OAuth2.0參數(shù)和實(shí)現(xiàn)授權(quán)流程(此處略,具體可參考官方文檔)。
4. 多賬號(hào)體系
如果系統(tǒng)中存在多種身份的用戶,例如普通用戶、管理員、商家等,可以使用多賬號(hào)體系進(jìn)行區(qū)分。
登錄指定賬號(hào)體系:
// 管理員登錄,loginKey為"admin" StpUtil.login(10001, "admin");
檢查登錄狀態(tài):
// 檢查當(dāng)前賬號(hào)體系下是否登錄
boolean isLogin = StpUtil.isLogin("admin");權(quán)限驗(yàn)證:
// 在指定賬號(hào)體系下進(jìn)行權(quán)限驗(yàn)證
StpUtil.checkPermission("user:update", "admin");四、Sa-Token使用總結(jié)
Sa-Token是一款輕量級(jí)的Java權(quán)限認(rèn)證框架,因其簡(jiǎn)單易用和功能豐富而備受開發(fā)者青睞。它以簡(jiǎn)潔明了的API設(shè)計(jì),使得集成和使用變得非常方便,開發(fā)者可以快速上手,降低了學(xué)習(xí)成本。Sa-Token支持多種權(quán)限控制需求,滿足復(fù)雜業(yè)務(wù)場(chǎng)景,包括登錄認(rèn)證、權(quán)限驗(yàn)證、角色驗(yàn)證、Session會(huì)話、多賬號(hào)體系等功能,全面覆蓋了權(quán)限管理的各個(gè)方面。其輕量級(jí)的設(shè)計(jì)對(duì)系統(tǒng)性能影響小,適用于高并發(fā)的應(yīng)用環(huán)境。此外,Sa-Token提供了豐富的擴(kuò)展接口,與Spring、Spring Boot等常用框架高度兼容,支持自定義持久化、注解方式驗(yàn)證、單點(diǎn)登錄等高級(jí)特性,方便開發(fā)者根據(jù)項(xiàng)目需求進(jìn)行定制開發(fā)?;钴S的社區(qū)支持和豐富的文檔資源也使得開發(fā)者能夠輕松獲取幫助和指導(dǎo)。
由于這些優(yōu)勢(shì),Sa-Token非常適合中小型項(xiàng)目的快速開發(fā)和微服務(wù)架構(gòu)下的權(quán)限管理。當(dāng)項(xiàng)目需要快速搭建權(quán)限系統(tǒng)時(shí),選擇Sa-Token是一個(gè)理想的方案。然而,在使用過程中需要注意Token的安全性,防止泄露帶來風(fēng)險(xiǎn);對(duì)于高并發(fā)場(chǎng)景,建議使用Redis等持久化介質(zhì)來提高系統(tǒng)性能和擴(kuò)展性;同時(shí),關(guān)注Sa-Token的版本更新,及時(shí)獲取新功能和安全補(bǔ)丁,以確保系統(tǒng)的安全性和穩(wěn)定性。
到此這篇關(guān)于SpringBoot權(quán)限認(rèn)證-Sa-Token的使用詳解的文章就介紹到這了,更多相關(guān)SpringBoot權(quán)限認(rèn)證Sa-Token內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java數(shù)據(jù)庫(kù)批量插入數(shù)據(jù)的實(shí)現(xiàn)
本文主要介紹了java數(shù)據(jù)庫(kù)批量插入數(shù)據(jù)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-05-05
Java8的DateTimeFormatter與SimpleDateFormat的區(qū)別詳解
這篇文章主要介紹了Java8的DateTimeFormatter與SimpleDateFormat的區(qū)別詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
一文詳解java如何實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用
從?Java?8?開始,便引入了一種稱為“流式?API”的編程風(fēng)格,當(dāng)然也被稱為“鏈?zhǔn)皆O(shè)置”或“鏈?zhǔn)秸{(diào)用”,本文主要來和大家討論一下如何實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用,感興趣的可以了解下2023-12-12
Java toString方法重寫工具之ToStringBuilder案例詳解
這篇文章主要介紹了Java toString方法重寫工具之ToStringBuilder案例詳解,本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08
Java實(shí)現(xiàn)圖片與Base64編碼互轉(zhuǎn)
這篇文章主要介紹了Java中實(shí)現(xiàn)圖片與Base64編碼互轉(zhuǎn)的方法,比較實(shí)用,需要的朋友可以參考下。2016-06-06
Java Swing實(shí)現(xiàn)坦克大戰(zhàn)游戲
這篇文章主要介紹了Java Swing實(shí)現(xiàn)坦克大戰(zhàn)游戲,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有很大的幫助喲,需要的朋友可以參考下2021-05-05
java實(shí)現(xiàn)簡(jiǎn)單的汽車租賃系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)簡(jiǎn)單的汽車租賃系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02
Java實(shí)現(xiàn)單例模式的五種方式總結(jié)
這篇文章主要介紹了如何實(shí)現(xiàn)一個(gè)單例模式,包括構(gòu)造器私有化、提供靜態(tài)私有變量和公共獲取實(shí)例接口,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-01-01

