templates.service.SaTokenConfig.ftl Maven / Gradle / Ivy
package ${packageName}.service.config;
import cn.dev33.satoken.exception.BackResultException;
import cn.dev33.satoken.exception.StopMatchException;
import cn.dev33.satoken.reactor.context.SaReactorHolder;
import cn.dev33.satoken.reactor.context.SaReactorSyncHolder;
import cn.dev33.satoken.reactor.filter.SaReactorFilter;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilterChain;
import ${packageName}.common.annotation.Inner;
import reactor.core.publisher.Mono;
import java.util.Collections;
import java.util.Objects;
/**
* @author Co.
* @name SaTokenConfig
* @date 2023/2/27 17:45
*/
@Order(200)
@Configuration
public class SaTokenConfig extends SaReactorFilter {
@Autowired
private SaTokenIgnoreUrlsConfig saTokenIgnoreUrlsConfig;
@Resource
private RequestMappingHandlerMapping requestMappingHandlerMapping;
@Bean
public void initSa() {
this.setExcludeList(saTokenIgnoreUrlsConfig.getUrls());
//TODO 这个需要改成你的实质请求前缀
this.setIncludeList(Collections.singletonList("/api/front/**"));
}
@Override
public Mono filter(ServerWebExchange exchange, WebFilterChain chain) {
return requestMappingHandlerMapping.getHandler(exchange).switchIfEmpty(chain.filter(exchange))
.flatMap(f -> {
HandlerMethod a = (HandlerMethod) f;
Inner annotation = a.getMethod().getAnnotation(Inner.class);
// 写入WebFilterChain对象
exchange.getAttributes().put(SaReactorHolder.CHAIN_KEY, chain);
// ---------- 全局认证处理
try {
// 写入全局上下文 (同步)
SaReactorSyncHolder.setContext(exchange);
// 执行全局过滤器
if (!Objects.nonNull(annotation)) {
// 登录验证 -- 排除多个路径
SaRouter.match(getIncludeList())
.notMatch(getExcludeList())
.check(r -> StpUtil.checkLogin());
}
} catch (StopMatchException e) {
} catch (Throwable e) {
// 1. 获取异常处理策略结果
String result = (e instanceof BackResultException) ? e.getMessage() : String.valueOf(error.run(e));
// 2. 写入输出流
if (exchange.getResponse().getHeaders().getFirst("Content-Type") == null) {
exchange.getResponse().getHeaders().set("Content-Type", "text/plain; charset=utf-8");
}
return exchange.getResponse().writeWith(Mono.just(exchange.getResponse().bufferFactory().wrap(result.getBytes())));
} finally {
// 清除上下文
SaReactorSyncHolder.clearContext();
}
// 写入全局上下文 (同步)
SaReactorSyncHolder.setContext(exchange);
// 执行
return chain.filter(exchange).contextWrite(ctx -> {
// 写入全局上下文 (异步)
ctx = ctx.put(SaReactorHolder.CONTEXT_KEY, exchange);
return ctx;
}).doFinally(r -> {
// 清除上下文
SaReactorSyncHolder.clearContext();
});
});
}
}