最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

springboot整合Sa-Token實(shí)現(xiàn)登錄認(rèn)證和權(quán)限校驗(yàn)的詳細(xì)流程

 更新時(shí)間:2025年09月18日 15:07:03   作者:張喬24  
Sa-Token是國(guó)產(chǎn)輕量級(jí)權(quán)限認(rèn)證框架,支持登錄、權(quán)限校驗(yàn)、單點(diǎn)登錄及分布式會(huì)話,配置簡(jiǎn)便且API設(shè)計(jì)直觀,相比Spring Security更易上手,適合快速實(shí)現(xiàn)安全功能,助力國(guó)產(chǎn)開源發(fā)展,感興趣的朋友跟隨小編一起看看吧

目前在國(guó)內(nèi)的后端開發(fā)中,常用的安全框架有spring security、shiro?,F(xiàn)在,介紹一款由國(guó)人開發(fā)的安全框架Sa-Token。這個(gè)框架完全由國(guó)人開發(fā),所提供的Api文檔和一些設(shè)置都是比較符合國(guó)人的開發(fā)習(xí)慣的,本次就來介紹一下如何在spring boot框架中整合Sa-Token框架,以實(shí)現(xiàn)我們最常使用的登錄認(rèn)證和權(quán)限校驗(yàn);

Sa-Token的官網(wǎng)地址如下:
Sa-Token

Sa-Token 是由國(guó)人開發(fā)的 一個(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)問題。

版本:spring boot3.15、Sa-Token1.37.0

1、新建一個(gè)spring boot項(xiàng)目,并導(dǎo)入一些起始的依賴:

<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.32</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.18</version>
        </dependency>
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
            <version>4.3.0</version>
        </dependency>
        <!-- Sa-Token 權(quán)限認(rèn)證,在線文檔:https://sa-token.cc -->
        <dependency>
            <groupId>cn.dev33</groupId>
            <artifactId>sa-token-spring-boot3-starter</artifactId>
            <version>1.37.0</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

2、新建五張數(shù)據(jù)表,來展示登錄認(rèn)證和權(quán)限校驗(yàn):

1、用戶表

CREATE TABLE users (
  id INT AUTO_INCREMENT PRIMARY KEY,
  username VARCHAR(50) NOT NULL UNIQUE,
  password VARCHAR(100) NOT NULL,
  email VARCHAR(100) NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

2、角色表

CREATE TABLE roles (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(50) NOT NULL UNIQUE,
  description VARCHAR(255),
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

3、權(quán)限表

CREATE TABLE permissions (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(50) NOT NULL UNIQUE,
  description VARCHAR(255),
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

4、用戶角色表

CREATE TABLE user_roles (
  id INT AUTO_INCREMENT PRIMARY KEY,
  user_id INT NOT NULL,
  role_id INT NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (user_id) REFERENCES users(id),
  FOREIGN KEY (role_id) REFERENCES roles(id)
);

5、角色權(quán)限表

CREATE TABLE role_permissions (
  id INT AUTO_INCREMENT PRIMARY KEY,
  role_id INT NOT NULL,
  permission_id INT NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (role_id) REFERENCES roles(id),
  FOREIGN KEY (permission_id) REFERENCES permissions(id)
);

3、現(xiàn)在我們開始進(jìn)行基于Sa-Token進(jìn)行的登錄校驗(yàn)和權(quán)限認(rèn)證:

與spring security不同的是,引入了Sa-Token的依賴之后。并不會(huì)自動(dòng)生效,需要我們自己編寫相應(yīng)的邏輯代碼;

寫一個(gè)TestController,用來進(jìn)行測(cè)試;

@RestController
@RequestMapping("/test")
public class TestController {
    @GetMapping("/hello")
    public String hello() {
        System.out.println("說hello啊");
        return "test接口的hello";
    }
}

我們現(xiàn)在啟動(dòng)項(xiàng)目,并訪問/test/hello接口,發(fā)現(xiàn)能夠正常訪問。這一點(diǎn)與spring security是不同的,spring security默認(rèn)會(huì)攔截所有請(qǐng)求;

Sa-Token已經(jīng)為我們編寫了很多我們經(jīng)常使用的功能,我們只需要在yml配置文件中進(jìn)行配置即可。以下是一些常用的配置:

############## Sa-Token 配置 (文檔: https://sa-token.cc) ##############
sa-token: 
    # token 名稱(同時(shí)也是 cookie 名稱)
    token-name: satoken
    # token 有效期(單位:秒) 默認(rèn)30天,-1 代表永久有效
    timeout: 2592000
    # token 最低活躍頻率(單位:秒),如果 token 超過此時(shí)間沒有訪問系統(tǒng)就會(huì)被凍結(jié),默認(rèn)-1 代表不限制,永不凍結(jié)
    active-timeout: -1
    # 是否允許同一賬號(hào)多地同時(shí)登錄 (為 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)格(默認(rèn)可取值:uuid、simple-uuid、random-32、random-64、random-128、tik)
    token-style: uuid
    # 是否輸出操作日志 
    is-log: true

3.1、登錄認(rèn)證:

使用Sa-Token進(jìn)行登錄認(rèn)證是非常簡(jiǎn)單的,只需要一句代碼就可以搞定:

// 會(huì)話登錄:參數(shù)填寫要登錄的賬號(hào)id,建議的數(shù)據(jù)類型:long | int | String, 不可以傳入復(fù)雜類型,如:User、Admin 等等
StpUtil.login(Object id);     

只此一句代碼,便可以使會(huì)話登錄成功,實(shí)際上,Sa-Token 在背后做了大量的工作,包括但不限于:

  1. 檢查此賬號(hào)是否之前已有登錄;
  2. 為賬號(hào)生成 Token 憑證與 Session 會(huì)話;
  3. 記錄 Token 活躍時(shí)間;
  4. 通知全局偵聽器,xx 賬號(hào)登錄成功;
  5. 將 Token 注入到請(qǐng)求上下文;
  6. 等等其它工作……

我們暫時(shí)不需要完整了解整個(gè)登錄過程,只需要記住關(guān)鍵一點(diǎn):Sa-Token 為這個(gè)賬號(hào)創(chuàng)建了一個(gè)Token憑證,且通過 Cookie 上下文返回給了前端。

一個(gè)登錄接口:

@Autowired
    IUsersService usersService;
    @PostMapping("/login")
public SaResult login(String username, String password){
//根據(jù)用戶名從數(shù)據(jù)庫(kù)中查詢
        Users users = usersService.getOne(new LambdaQueryWrapper<Users>().eq(Users::getUsername, username));
        if(users == null){
            return SaResult.error("用戶名不存在");
        }
        if(!users.getPassword().equals(password)){
    return SaResult.error("密碼錯(cuò)誤");
    }
//根據(jù)用戶id登錄
        StpUtil.login(users.getId());
        return SaResult.ok("登錄成功");
    }

運(yùn)行檢驗(yàn):

發(fā)現(xiàn)確實(shí)能夠登錄成功。

此處僅僅做了會(huì)話登錄,但并沒有主動(dòng)向前端返回 token 信息。 是因?yàn)椴恍枰獑???yán)格來講是需要的,只不過 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ì)話暫未登錄,可能的原因有很多: 前端沒有提交 token、前端提交的 token 是無效的、前端提交的 token 已經(jīng)過期 …… 等等

還有一些登錄過程中常用的方法:

// 獲取當(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);
// 獲取當(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();

3.1.1前后端分離模式下的登錄(無cookie模式)

無 Cookie 模式:特指不支持 Cookie 功能的終端,通俗來講就是我們常說的 —— 前后端分離模式。

常規(guī) Web 端鑒權(quán)方法,一般由 Cookie模式 完成,而 Cookie 有兩個(gè)特性:

  1. 可由后端控制寫入。
  2. 每次請(qǐng)求自動(dòng)提交。

這就使得我們?cè)谇岸舜a中,無需任何特殊操作,就能完成鑒權(quán)的全部流程(因?yàn)檎麄€(gè)流程都是后端控制完成的)

而在app、小程序等前后端分離場(chǎng)景中,一般是沒有 Cookie 這一功能的,此時(shí)大多數(shù)人都會(huì)一臉懵逼,咋進(jìn)行鑒權(quán)???

見招拆招,其實(shí)答案很簡(jiǎn)單:

  • 不能后端控制寫入了,就前端自己寫入。(后端將登錄成功之后生成的Token 傳遞到前端
  • 每次請(qǐng)求不能自動(dòng)提交了,那就手動(dòng)提交。(前端將登陸成功后獲取的Token封裝到請(qǐng)求頭中每次請(qǐng)求時(shí)都攜帶后端將其讀取出來,并判斷用戶信息

修改我們之前寫的登錄接口,返回token給前端;

 @PostMapping("/login")
public SaResult login(String username, String password){
//根據(jù)用戶名從數(shù)據(jù)庫(kù)中查詢
        Users users = usersService.getOne(new LambdaQueryWrapper<Users>().eq(Users::getUsername, username));
        if(users == null){
            return SaResult.error("用戶名不存在");
        }
        if(!users.getPassword().equals(password)){
    return SaResult.error("密碼錯(cuò)誤");
    }
//根據(jù)用戶id登錄,第1步,先登錄上
        StpUtil.login(users.getId());
        // 第2步,獲取 Token  相關(guān)參數(shù) 
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
        // 第3步,返回給前端 
        return SaResult.data(tokenInfo);
    }

在進(jìn)行一次登錄:

可以看到登錄成功之后,返回了很多相關(guān)的數(shù)據(jù),而我們的token也在其中,那么前端就可以將token取出來放到一個(gè)狀態(tài)管理器(pinia中),并且在每次請(qǐng)求時(shí)都將token放在請(qǐng)求頭中。

如果你對(duì) Cookie 非常了解,那你就會(huì)明白,所謂 Cookie ,本質(zhì)上就是一個(gè)特殊的header參數(shù)而已, 而既然它只是一個(gè) header 參數(shù),我們就能手動(dòng)模擬實(shí)現(xiàn)它,從而完成鑒權(quán)操作。

3.1.2路由攔截鑒權(quán):

假設(shè)我們有如下需求:

項(xiàng)目中所有接口均需要登錄認(rèn)證,只有 “登錄接口” 本身對(duì)外開放

我們?cè)趺磳?shí)現(xiàn)呢?給每個(gè)接口加上鑒權(quán)注解?手寫全局?jǐn)r截器?似乎都不是非常方便。

在這個(gè)需求中我們真正需要的是一種基于路由攔截的鑒權(quán)模式,那么在Sa-Token怎么實(shí)現(xiàn)路由攔截鑒權(quán)呢?

@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {
    // 注冊(cè)攔截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注冊(cè) Sa-Token 攔截器,校驗(yàn)規(guī)則為 StpUtil.checkLogin() 登錄校驗(yàn)。
        registry.addInterceptor(new SaInterceptor(handle -> StpUtil.checkLogin()))
                .addPathPatterns("/**")
                .excludePathPatterns("/users/login");
    }
}

以上代碼,我們注冊(cè)了一個(gè)基于 StpUtil.checkLogin() 的登錄校驗(yàn)攔截器,并且排除了/user/login接口用來開放登錄(除了/user/login以外的所有接口都需要登錄才能訪問)這就與我們spring security有了一點(diǎn)點(diǎn)相似了,因?yàn)閟pring security默認(rèn)的就是所有的接口都被攔截到。

我們?cè)賳?dòng)項(xiàng)目,并訪問我們最開始寫的/test/hello接口;

可以看到這個(gè)接口被攔截了。那么我們帶上之前登錄成功,生成的token之后再去訪問呢?

可以看到我們成功訪問了這個(gè)接口;

new SaInterceptor(handle -> StpUtil.checkLogin()) 是最簡(jiǎn)單的寫法,代表只進(jìn)行登錄校驗(yàn)功能。實(shí)際上Sa-Token還可以實(shí)現(xiàn)一些更詳細(xì)的校驗(yàn)規(guī)則,在Sa-Token的官網(wǎng)上可以看到。

3.1.3持久化

Sa-Token 默認(rèn)將數(shù)據(jù)保存在內(nèi)存中,此模式讀寫速度最快,且避免了序列化與反序列化帶來的性能消耗,但是此模式也有一些缺點(diǎn),比如:

  1. 重啟后數(shù)據(jù)會(huì)丟失。
  2. 無法在分布式環(huán)境中共享數(shù)據(jù)。

所以,sa-token為我們提供了持久化的方法,我們可以在登錄成功之后將token數(shù)據(jù)存儲(chǔ)到redis中。然后,每次請(qǐng)求時(shí)到redis中取到我們的token數(shù)據(jù)。這樣就實(shí)現(xiàn)了即使重啟服務(wù),我們之前的登錄token也不會(huì)丟失

<!-- Sa-Token 整合 Redis (使用 jackson 序列化方式) -->
<dependency>
    <groupId>cn.dev33</groupId>
    <artifactId>sa-token-redis-jackson</artifactId>
    <version>1.37.0</version>
</dependency>

sa-token已經(jīng)幫我們整合了redis,我們自需要引入相應(yīng)的pom依賴。其他的上層Api都不變。

3.2權(quán)限校驗(yàn):

我們已經(jīng)了解了常用的登錄認(rèn)證方法,接下來,我們來看一下權(quán)限校驗(yàn);

1、獲取當(dāng)前用戶的權(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)限加載接口實(shí)現(xiàn)類
 */
@Component    // 保證此類被 SpringBoot 掃描,完成 Sa-Token 的自定義權(quán)限驗(yàn)證擴(kuò)展
public class StpInterfaceImpl implements StpInterface {
    /**
     * 返回一個(gè)賬號(hào)所擁有的權(quán)限碼集合 
     */
//    角色權(quán)限表
    @Autowired
    IRolePermissionsService rolePermissionsService;
//    用戶角色表
    @Autowired
    IUserRolesService userRolesService;
//權(quán)限表
    @Autowired
    IPermissionsService permissionsService;
//    角色表
    @Autowired
    IRolesService rolesService;
    @Override
    public List<String> getPermissionList(Object loginId, String loginType) {
//        根據(jù)用戶id從用戶角色表中獲取角色id
        List<UserRoles> roleIds = userRolesService.list(new LambdaQueryWrapper<UserRoles>()
                .eq(UserRoles::getUserId,Integer.parseInt(loginId.toString())));
        List<Integer> rolesList = roleIds.stream().map(UserRoles::getRoleId).toList();
if (!(rolesList.size() >0)){
//    沒有任何權(quán)限
    return null;
}
        List<String> list = new ArrayList<>();
        rolesList.forEach(roleId ->{
            // 根據(jù)角色id從角色權(quán)限表中獲取權(quán)限id   
            List<RolePermissions> rolePermissions = rolePermissionsService.list(new LambdaQueryWrapper<RolePermissions>().
                    eq(RolePermissions::getRoleId, roleId));
            // 根據(jù)權(quán)限id從權(quán)限表中獲取權(quán)限名稱
            rolePermissions.forEach(permissionsId->{
                Permissions permissions = permissionsService.getById(permissionsId.getPermissionId());
                list.add(permissions.getName());
            });
        });
        // 返回用戶所有權(quán)限,
        return list;
    }
    /**
     * 返回一個(gè)賬號(hào)所擁有的角色標(biāo)識(shí)集合 (權(quán)限與角色可分開校驗(yàn))
     */
    @Override
    public List<String> getRoleList(Object loginId, String loginType) {
        // 本 list 僅做模擬,實(shí)際項(xiàng)目中要根據(jù)具體業(yè)務(wù)邏輯來查詢角色
        //        根據(jù)用戶id從用戶角色表中獲取角色id
        List<UserRoles> roleIds = userRolesService.list(new LambdaQueryWrapper<UserRoles>()
                .eq(UserRoles::getUserId,Integer.parseInt(loginId.toString())));
        List<String> list = new ArrayList<>();
        if (!(roleIds.size() >0)){
//            用戶沒有分配角色
            return null;
        }
        roleIds.forEach(roleId ->{
            Roles byId = rolesService.getById(roleId.getRoleId());
            list.add(byId.getName());
        });
//        返回用戶所有角色標(biāo)識(shí)集合
        return list;
    }
}

我所實(shí)現(xiàn)的是標(biāo)準(zhǔn)的RBAC(基于用戶、角色、權(quán)限的訪問控制模型)。所以,在得到用戶id的情況下、先根據(jù)用戶角色表查出角色id、在根據(jù)角色權(quán)限表查詢權(quán)限id,在根據(jù)權(quán)限表查出具體權(quán)限名稱。

上面使用了Mybatis-plus的條件構(gòu)造器和stream流的形式進(jìn)行查詢。

參數(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ì)的解釋。

有同學(xué)會(huì)產(chǎn)生疑問:我實(shí)現(xiàn)了此接口,但是程序啟動(dòng)時(shí)好像并沒有執(zhí)行,是不是我寫錯(cuò)了? 答:不執(zhí)行是正?,F(xiàn)象,程序啟動(dòng)時(shí)不會(huì)執(zhí)行這個(gè)接口的方法,在每次調(diào)用鑒權(quán)代碼時(shí),才會(huì)執(zhí)行到此。

權(quán)限校驗(yàn):
然后就可以用以下 api 來鑒權(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)證未通過,則拋出異常: NotPermissionException 
StpUtil.checkPermission("user.add");        
// 校驗(yàn):當(dāng)前賬號(hào)是否含有指定權(quán)限 [指定多個(gè),必須全部驗(yàn)證通過]
StpUtil.checkPermissionAnd("user.add", "user.delete", "user.get");        
// 校驗(yàn):當(dāng)前賬號(hào)是否含有指定權(quán)限 [指定多個(gè),只要其一驗(yàn)證通過即可]
StpUtil.checkPermissionOr("user.add", "user.delete", "user.get");    

擴(kuò)展:NotPermissionException 對(duì)象可通過 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)證未通過,則拋出異常: NotRoleException
StpUtil.checkRole("super-admin");        
// 校驗(yàn):當(dāng)前賬號(hào)是否含有指定角色標(biāo)識(shí) [指定多個(gè),必須全部驗(yàn)證通過]
StpUtil.checkRoleAnd("super-admin", "shop-admin");        
// 校驗(yàn):當(dāng)前賬號(hào)是否含有指定角色標(biāo)識(shí) [指定多個(gè),只要其一驗(yàn)證通過即可] 
StpUtil.checkRoleOr("super-admin", "shop-admin");        

擴(kuò)展:NotRoleException 對(duì)象可通過 getLoginType() 方法獲取具體是哪個(gè) StpLogic 拋出的異常

權(quán)限通配符:
Sa-Token允許你根據(jù)通配符指定泛權(quán)限,例如當(dāng)一個(gè)賬號(hào)擁有art.*的權(quán)限時(shí),art.add、art.deleteart.update都將匹配通過

// 當(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)證通過任何權(quán)限碼 (角色認(rèn)證同理)

在我們的項(xiàng)目的TestController中進(jìn)行測(cè)試:

  @GetMapping("/hello")
    public String hello() {
        System.out.println("驗(yàn)證權(quán)限,是否具有‘所有權(quán)限'===============>"+StpUtil.hasPermission("所有權(quán)限"));
        System.out.println("驗(yàn)證角色,是否具有‘管理員'角色===============>"+StpUtil.hasRole("管理員"));  
        System.out.println("說hello啊");
        return "test接口的hello";
    }

我們測(cè)試的最終結(jié)果:

可以看到確實(shí)輸出了兩個(gè)true。并且,只有在每次調(diào)用鑒權(quán)代碼時(shí),才會(huì)執(zhí)行到我們自定義的權(quán)限方法中。

總結(jié):

我本來是想寫一篇介紹spring boot項(xiàng)目中整合Sa-Token來實(shí)現(xiàn)最常用的登錄校驗(yàn)和權(quán)限認(rèn)證的,但是寫著寫著就變成官網(wǎng)的復(fù)制機(jī)了。我在本篇文章中大量復(fù)制了官網(wǎng)上的內(nèi)容,原本只是想復(fù)制一些官方介紹就行了。但是這也從側(cè)面說明了Sa-Token官網(wǎng)制作的確實(shí)是比較好的,基本上不需要額外的學(xué)習(xí),只要你有做過登錄和權(quán)限方面的項(xiàng)目經(jīng)驗(yàn),再看一遍官網(wǎng)的介紹就能直接上手了。

我之前寫過一個(gè)B2C模式的購(gòu)物商臺(tái),分為用戶端和管理端。管理端的登錄和權(quán)限校驗(yàn)是用spring security寫的?,F(xiàn)在又了解了Sa-Token之后,真的還是認(rèn)為Sa-Token的使用是比較簡(jiǎn)單的。(也可能是我的項(xiàng)目還是比較簡(jiǎn)單的,并沒有多少權(quán)限要實(shí)現(xiàn))并且這也是我們國(guó)人寫的開源框架,在一些方法的封裝、Api的設(shè)計(jì)上還是能直接理解的。在這里也算是為Sa-Token這個(gè)框架打個(gè)廣告吧,希望大家還是能夠多多支持國(guó)產(chǎn),國(guó)內(nèi)的開源之路也是充滿了坎坷與艱辛。

到此這篇關(guān)于springboot整合Sa-Token實(shí)現(xiàn)登錄認(rèn)證和權(quán)限校驗(yàn)的詳細(xì)流程的文章就介紹到這了,更多相關(guān)springboot Sa-Token登錄認(rèn)證和權(quán)限校驗(yàn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot實(shí)現(xiàn)發(fā)送電子郵件

    SpringBoot實(shí)現(xiàn)發(fā)送電子郵件

    這篇文章主要介紹了SpringBoot實(shí)現(xiàn)發(fā)送電子郵件,電子郵件是—種用電子手段提供信息交換的通信方式,是互聯(lián)網(wǎng)應(yīng)用最廣的服務(wù)。通過網(wǎng)絡(luò)的電子郵件系統(tǒng),用戶可以非常快速的方式,與世界上任何一個(gè)角落的網(wǎng)絡(luò)用戶聯(lián)系,下面就來看看SpringBoot如何實(shí)現(xiàn)發(fā)送電子郵件吧
    2022-01-01
  • Mybatis單個(gè)參數(shù)的if判斷報(bào)異常There is no getter for property named ''xxx'' in ''class java.lang.Integer''的解決方案

    Mybatis單個(gè)參數(shù)的if判斷報(bào)異常There is no getter for property named ''x

    今天小編就為大家分享一篇關(guān)于Mybatis單個(gè)參數(shù)的if判斷報(bào)異常There is no getter for property named 'xxx' in 'class java.lang.Integer'的解決方案,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • IDEA集成git和使用步驟的實(shí)現(xiàn)方法

    IDEA集成git和使用步驟的實(shí)現(xiàn)方法

    這篇文章主要介紹了IDEA集成git和使用步驟的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • springboot 跨域配置類及跨域請(qǐng)求配置

    springboot 跨域配置類及跨域請(qǐng)求配置

    這篇文章主要介紹了springboot 跨域配置類及跨域請(qǐng)求配置,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-01-01
  • Java集合框架源碼分析之LinkedHashMap詳解

    Java集合框架源碼分析之LinkedHashMap詳解

    這篇文章主要介紹了Java集合框架源碼分析之LinkedHashMap詳解,內(nèi)容包括了linkedhashmap的簡(jiǎn)介和源碼剖析以及關(guān)于LinkedHashMap的源碼總結(jié),內(nèi)容豐富,需要的朋友可以參考下。
    2017-09-09
  • JAVA基于Arrays.sort()實(shí)現(xiàn)數(shù)組升序和降序

    JAVA基于Arrays.sort()實(shí)現(xiàn)數(shù)組升序和降序

    這篇文章主要介紹了JAVA基于Arrays.sort()實(shí)現(xiàn)數(shù)組升序和降序,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • Java深入淺出數(shù)組的定義與使用上篇

    Java深入淺出數(shù)組的定義與使用上篇

    數(shù)組是有序的元素序列,若將有限個(gè)類型相同的變量的集合命名,那么這個(gè)名稱為數(shù)組名。組成數(shù)組的各個(gè)變量稱為數(shù)組的分量,也稱為數(shù)組的元素,有時(shí)也稱為下標(biāo)變量。數(shù)組是在程序設(shè)計(jì)中,為了處理方便, 把具有相同類型的若干元素按有序的形式組織起來的一種形式
    2022-03-03
  • java 中 poi解析Excel文件版本問題解決辦法

    java 中 poi解析Excel文件版本問題解決辦法

    這篇文章主要介紹了java 中 poi解析Excel文件版本問題解決辦法的相關(guān)資料,需要的朋友可以參考下
    2017-08-08
  • 解決IDEA使用springBoot創(chuàng)建項(xiàng)目,lombok標(biāo)注實(shí)體類后編譯無報(bào)錯(cuò),但是運(yùn)行時(shí)報(bào)錯(cuò)問題

    解決IDEA使用springBoot創(chuàng)建項(xiàng)目,lombok標(biāo)注實(shí)體類后編譯無報(bào)錯(cuò),但是運(yùn)行時(shí)報(bào)錯(cuò)問題

    文章詳細(xì)描述了在使用lombok的@Data注解標(biāo)注實(shí)體類時(shí)遇到編譯無誤但運(yùn)行時(shí)報(bào)錯(cuò)的問題,分析了可能的原因,并提供了解決步驟
    2025-01-01
  • 剖析Java中阻塞隊(duì)列的實(shí)現(xiàn)原理及應(yīng)用場(chǎng)景

    剖析Java中阻塞隊(duì)列的實(shí)現(xiàn)原理及應(yīng)用場(chǎng)景

    這篇文章主要介紹了剖析Java中阻塞隊(duì)列的實(shí)現(xiàn)原理及應(yīng)用場(chǎng)景,這里也對(duì)阻塞和非阻塞隊(duì)列的不同之處進(jìn)行了對(duì)比,需要的朋友可以參考下
    2015-12-12

最新評(píng)論

新闻| 营口市| 临夏市| 鹤壁市| 鄱阳县| 宾川县| 夏津县| 洞头县| 板桥市| 朔州市| 琼海市| 来宾市| 通许县| 隆回县| 绍兴县| 荔波县| 响水县| 兴宁市| 泸溪县| 富裕县| 淮南市| 同江市| 济宁市| 乐昌市| 高安市| 西丰县| 大庆市| 临城县| 鹤山市| 阿瓦提县| 江阴市| 锦州市| 闵行区| 博客| 六安市| 吴江市| 策勒县| 合作市| 鹤庆县| 敦煌市| 碌曲县|