国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

SpringBoot 使用 Sa-Token 完成路由攔截鑒權(quán)

這篇具有很好參考價(jià)值的文章主要介紹了SpringBoot 使用 Sa-Token 完成路由攔截鑒權(quán)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

一、需求分析

在前文,我們?cè)敿?xì)的講述了在 Sa-Token 如何使用注解進(jìn)行權(quán)限認(rèn)證,注解鑒權(quán)雖然方便,卻并不適合所有鑒權(quán)場(chǎng)景。

假設(shè)有如下需求:項(xiàng)目中所有接口均需要登錄認(rèn)證校驗(yàn),只有 “登錄接口” 本身對(duì)外開放。

如果我們對(duì)項(xiàng)目所有接口都加上 @SaCheckLogin 注解,會(huì)顯得非常冗余且沒有必要,在這個(gè)需求中我們真正需要的是一種基于路由攔截的鑒權(quán)模式,那么在 Sa-Token 怎么實(shí)現(xiàn)路由攔截鑒權(quán)呢?

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

二、注冊(cè) 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 即可。

新建配置類SaTokenConfigure.java

@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("/user/doLogin"); 
	}
}

以上代碼,我們注冊(cè)了一個(gè)基于 StpUtil.checkLogin() 的登錄校驗(yàn)攔截器,并且排除了/user/doLogin接口用來開放登錄(除了/user/doLogin以外的所有接口都需要登錄才能訪問)。

SaInterceptor 是新版本提供的攔截器,點(diǎn)此 查看舊版本代碼遷移示例。

三、校驗(yàn)函數(shù)詳解

自定義認(rèn)證規(guī)則:new SaInterceptor(handle -> StpUtil.checkLogin()) 是最簡(jiǎn)單的寫法,代表只進(jìn)行登錄校驗(yàn)功能。

我們可以往構(gòu)造函數(shù)塞一個(gè)完整的 lambda 表達(dá)式,來定義詳細(xì)的校驗(yàn)規(guī)則,例如:

@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		// 注冊(cè) Sa-Token 攔截器,定義詳細(xì)認(rèn)證規(guī)則 
		registry.addInterceptor(new SaInterceptor(handler -> {
			// 指定一條 match 規(guī)則
			SaRouter
				.match("/**")	// 攔截的 path 列表,可以寫多個(gè) */
				.notMatch("/user/doLogin")		// 排除掉的 path 列表,可以寫多個(gè) 
				.check(r -> StpUtil.checkLogin());		// 要執(zhí)行的校驗(yàn)動(dòng)作,可以寫完整的 lambda 表達(dá)式
				
			// 根據(jù)路由劃分模塊,不同模塊不同鑒權(quán) 
			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"));
			SaRouter.match("/comment/**", r -> StpUtil.checkPermission("comment"));
		})).addPathPatterns("/**");
	}
}

SaRouter.match() 匹配函數(shù)有兩個(gè)參數(shù):

  • 參數(shù)一:要匹配的path路由。
  • 參數(shù)二:要執(zhí)行的校驗(yàn)函數(shù)。

在校驗(yàn)函數(shù)內(nèi)不只可以使用 StpUtil.checkPermission("xxx") 進(jìn)行權(quán)限校驗(yàn),你還可以寫任意代碼,例如:

@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {
	// 注冊(cè) Sa-Token 的攔截器
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		// 注冊(cè)路由攔截器,自定義認(rèn)證規(guī)則 
		registry.addInterceptor(new SaInterceptor(handler -> {
			
			// 登錄校驗(yàn) -- 攔截所有路由,并排除/user/doLogin 用于開放登錄 
			SaRouter.match("/**", "/user/doLogin", r -> StpUtil.checkLogin());

			// 角色校驗(yàn) -- 攔截以 admin 開頭的路由,必須具備 admin 角色或者 super-admin 角色才可以通過認(rèn)證 
			SaRouter.match("/admin/**", r -> StpUtil.checkRoleOr("admin", "super-admin"));

			// 權(quán)限校驗(yàn) -- 不同模塊校驗(yàn)不同權(quán)限 
			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"));
			SaRouter.match("/comment/**", r -> StpUtil.checkPermission("comment"));
			
			// 甚至你可以隨意的寫一個(gè)打印語(yǔ)句
			SaRouter.match("/**", r -> System.out.println("----啦啦啦----"));

            // 連綴寫法
            SaRouter.match("/**").check(r -> System.out.println("----啦啦啦----"));
			
		})).addPathPatterns("/**");
	}
}

四、匹配特征詳解

除了上述示例的 path 路由匹配,還可以根據(jù)很多其它特征進(jìn)行匹配,以下是所有可匹配的特征:

// 基礎(chǔ)寫法樣例:匹配一個(gè)path,執(zhí)行一個(gè)校驗(yàn)函數(shù) 
SaRouter.match("/user/**").check(r -> StpUtil.checkLogin());

// 根據(jù) path 路由匹配   ——— 支持寫多個(gè)path,支持寫 restful 風(fēng)格路由 
// 功能說明: 使用 /user , /goods 或者 /art/get 開頭的任意路由都將進(jìn)入 check 方法
SaRouter.match("/user/**", "/goods/**", "/art/get/{id}").check( /* 要執(zhí)行的校驗(yàn)函數(shù) */ );

// 根據(jù) path 路由排除匹配 
// 功能說明: 使用 .html , .css 或者 .js 結(jié)尾的任意路由都將跳過, 不會(huì)進(jìn)入 check 方法
SaRouter.match("/**").notMatch("*.html", "*.css", "*.js").check( /* 要執(zhí)行的校驗(yàn)函數(shù) */ );

// 根據(jù)請(qǐng)求類型匹配 
SaRouter.match(SaHttpMethod.GET).check( /* 要執(zhí)行的校驗(yàn)函數(shù) */ );

// 根據(jù)一個(gè) boolean 條件進(jìn)行匹配 
SaRouter.match( StpUtil.isLogin() ).check( /* 要執(zhí)行的校驗(yàn)函數(shù) */ );

// 根據(jù)一個(gè)返回 boolean 結(jié)果的lambda表達(dá)式匹配 
SaRouter.match( r -> StpUtil.isLogin() ).check( /* 要執(zhí)行的校驗(yàn)函數(shù) */ );

// 多個(gè)條件一起使用 
// 功能說明: 必須是 Get 請(qǐng)求 并且 請(qǐng)求路徑以 `/user/` 開頭 
SaRouter.match(SaHttpMethod.GET).match("/user/**").check( /* 要執(zhí)行的校驗(yàn)函數(shù) */ );

// 可以無限連綴下去 
// 功能說明: 同時(shí)滿足 Get 方式請(qǐng)求, 且路由以 /admin 開頭, 路由中間帶有 /send/ 字符串, 路由結(jié)尾不能是 .js 和 .css
SaRouter
	.match(SaHttpMethod.GET)
	.match("/admin/**")
	.match("/**/send/**") 
	.notMatch("/**/*.js")
	.notMatch("/**/*.css")
	// ....
	.check( /* 只有上述所有條件都匹配成功,才會(huì)執(zhí)行最后的check校驗(yàn)函數(shù) */ );

五、提前退出匹配鏈

使用 SaRouter.stop() 可以提前退出匹配鏈,例:

registry.addInterceptor(new SaInterceptor(handler -> {
	SaRouter.match("/**").check(r -> System.out.println("進(jìn)入1"));
	SaRouter.match("/**").check(r -> System.out.println("進(jìn)入2")).stop();
	SaRouter.match("/**").check(r -> System.out.println("進(jìn)入3"));
	SaRouter.match("/**").check(r -> System.out.println("進(jìn)入4"));
	SaRouter.match("/**").check(r -> System.out.println("進(jìn)入5"));
})).addPathPatterns("/**");

如上示例,代碼運(yùn)行至第2條匹配鏈時(shí),會(huì)在stop函數(shù)處提前退出整個(gè)匹配函數(shù),從而忽略掉剩余的所有match匹配

除了stop()函數(shù),SaRouter還提供了 back() 函數(shù),用于:停止匹配,結(jié)束執(zhí)行,直接向前端返回結(jié)果

// 執(zhí)行back函數(shù)后將停止匹配,也不會(huì)進(jìn)入Controller,而是直接將 back參數(shù) 作為返回值輸出到前端
SaRouter.match("/user/back").back("要返回到前端的內(nèi)容");

stop() 與 back() 函數(shù)的區(qū)別在于:

  • SaRouter.stop() 會(huì)停止匹配,進(jìn)入Controller。
  • SaRouter.back() 會(huì)停止匹配,直接返回結(jié)果到前端。

六、使用free打開一個(gè)獨(dú)立的作用域

// 進(jìn)入 free 獨(dú)立作用域 
SaRouter.match("/**").free(r -> {
	SaRouter.match("/a/**").check(/* --- */);
	SaRouter.match("/b/**").check(/* --- */).stop();
	SaRouter.match("/c/**").check(/* --- */);
});
// 執(zhí)行 stop() 函數(shù)跳出 free 后繼續(xù)執(zhí)行下面的 match 匹配 
SaRouter.match("/**").check(/* --- */);

free() 的作用是:打開一個(gè)獨(dú)立的作用域,使內(nèi)部的 stop() 不再一次性跳出整個(gè) Auth 函數(shù),而是僅僅跳出當(dāng)前 free 作用域。

七、使用注解忽略掉路由攔截校驗(yàn)

我們可以使用 @SaIgnore 注解,忽略掉路由攔截認(rèn)證:

1、先配置好了攔截規(guī)則:

@Override
public void addInterceptors(InterceptorRegistry registry) {
	registry.addInterceptor(new SaInterceptor(handler -> {
		// 根據(jù)路由劃分模塊,不同模塊不同鑒權(quán) 
		SaRouter.match("/user/**", r -> StpUtil.checkPermission("user"));
		SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
		SaRouter.match("/goods/**", r -> StpUtil.checkPermission("goods"));
		// ... 
	})).addPathPatterns("/**");
}

2、然后在 Controller 里又添加了忽略校驗(yàn)的注解

@SaIgnore
@RequestMapping("/user/getList")
public SaResult getList() {
	System.out.println("------------ 訪問進(jìn)來方法"); 
	return SaResult.ok(); 
}

請(qǐng)求將會(huì)跳過攔截器的校驗(yàn),直接進(jìn)入 Controller 的方法中。

注意點(diǎn):此注解的忽略效果只針對(duì) SaInterceptor攔截器 和 AOP注解鑒權(quán) 生效,對(duì)自定義攔截器與過濾器不生效。

八、關(guān)閉注解校驗(yàn)

SaInterceptor 只要注冊(cè)到項(xiàng)目中,默認(rèn)就會(huì)打開注解校驗(yàn),如果要關(guān)閉此能力,需要:文章來源地址http://www.zghlxwxcb.cn/news/detail-454015.html

@Override
public void addInterceptors(InterceptorRegistry registry) {
	registry.addInterceptor(
		new SaInterceptor(handle -> {
			SaRouter.match("/**").check(r -> StpUtil.checkLogin());
		}).isAnnotation(false)  // 指定關(guān)閉掉注解鑒權(quán)能力,這樣框架就只會(huì)做路由攔截校驗(yàn)了 
	).addPathPatterns("/**");
}

參考資料

  • Sa-Token 文檔:https://sa-token.cc
  • Gitee 倉(cāng)庫(kù)地址:https://gitee.com/dromara/sa-token
  • GitHub 倉(cāng)庫(kù)地址:https://github.com/dromara/sa-token

到了這里,關(guān)于SpringBoot 使用 Sa-Token 完成路由攔截鑒權(quán)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包