sa-token/sa-token-doc/fun/dynamic-router-check.md
2022-10-10 00:59:08 +08:00

2.1 KiB
Raw Blame History

参考:把路由拦截鉴权动态化

框架提供的示例是硬代码写死的,不过稍微做一下更改,你就可以让他动态化


参考如下:

@Override
public void addInterceptors(InterceptorRegistry registry) {
	registry.addInterceptor(new SaInterceptor(handle -> {
		SaRouter
			.match("/**")
			.notMatch(excludePaths())
			.check(r -> StpUtil.checkLogin());
	})).addPathPatterns("/**");
}

// 动态获取哪些 path 可以忽略鉴权 
public List<String> excludePaths() {
	// 此处仅为示例实际项目你可以写任意代码来查询这些path
	return Arrays.asList("/path1", "/path2", "/path3");
}

如果不仅仅是登录校验,还需要鉴权,那也很简单:

@Override
public void addInterceptors(InterceptorRegistry registry) {
	registry.addInterceptor(new SaInterceptor(handle -> {
		// 遍历校验规则,依次鉴权 
		Map<String, String> rules = getAuthRules();
		for (String path : rules.keySet()) {
			SaRouter.match(path, () -> StpUtil.checkPermission(rules.get(path)));
		}
	})).addPathPatterns("/**");
}

// 动态获取鉴权规则 
public Map<String, String> getAuthRules() {
	// key 代表要拦截的 pathvalue 代表需要校验的权限 
	Map<String, String> authMap = new LinkedHashMap<>();
	authMap.put("/user/**", "user");
	authMap.put("/admin/**", "admin");
	authMap.put("/article/**", "article");
	// 更多规则 ... 
	return authMap;
}

错误的写法:

@Override
public void addInterceptors(InterceptorRegistry registry) {
	registry.addInterceptor(new SaInterceptor(handle -> {
		StpUtil.checkLogin();
	}))
	.addPathPatterns("/**")
	.excludePathPatterns(excludePaths());
}

// 动态获取哪些 path 可以忽略鉴权 
public List<String> excludePaths() {
	// 此处仅为示例实际项目你可以写任意代码来查询这些path
	return Arrays.asList("/path1", "/path2", "/path3");
}

错误点:因为 lambda 表达式之外的代码只会在启动时执行一次,所以 excludePaths() 方法是无法做到动态化读取的, 若要在项目运行时动态读写,必须把调用 excludePaths() 的时机放在 lambda 里。