用了好几种处理跨域的方法,只有下面这种成功了
@Configuration
public class CorsConfig {
/**
* 配置跨域访问执行
*/
@Bean
public CorsWebFilter corsWebFilter(){
//cors跨域配置对象
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);//是否允许携带cookie
config.addAllowedOriginPattern("*"); //允许跨域访问的域名,可填写具体域名,*代表允许所有访问
config.addAllowedMethod("*");//允许访问类型:get post 等,*代表所有类型
config.addAllowedHeader("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
//配置源对象
source.registerCorsConfiguration("/**",config);
return new CorsWebFilter(source);
}
}
为了登录认证增加过滤器,因项目中使用satoken,没找到起官方有合适的方法,所以在过滤器中用逻辑代替,朋友们发现官方有更好的方案希望能留言提醒,感谢~
@Slf4j
@Component
@RequiredArgsConstructor
public class AuthorizeFilter implements GlobalFilter, Ordered {
private static final String TRACE_ID = "traceId";
private static final AntPathMatcher matcher = new AntPathMatcher();
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
//对请求对象request进行增强
ServerHttpRequest req = request.mutate().headers(httpHeaders -> {
//httpHeaders 封装了所有的请求头
String traceId = UUID.randomUUID().toString(true);
MDC.put(TRACE_ID, traceId);
httpHeaders.set(TRACE_ID, traceId);
}).build();
//设置增强的request到exchange对象中
exchange.mutate().request(req);
String url = request.getURI().getPath();
log.info("接收到请求:{}", url);
// 不需要拦截的接口直接放行
if (needLogin(request.getPath().toString())) {
return getVoidMono(exchange, chain);
} else {
// 登录认证
String token = request.getHeaders().getFirst("token");
Object loginId = StpUtil.getLoginIdByToken(token);
if (loginId == null) {
// 未登录 结束请求
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
}
log.info("认证成功,放行");
return getVoidMono(exchange, chain);
}
private Mono<Void> getVoidMono(ServerWebExchange exchange, GatewayFilterChain chain) {
return chain.filter(exchange).then(Mono.defer(() -> {
exchange.getResponse().getHeaders().entrySet().stream()
.filter(kv -> kv.getValue() != null && kv.getValue().size() > 1)
.filter(kv -> kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)
|| kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS))
.forEach(kv -> kv.setValue(Collections.singletonList(kv.getValue().get(0))));
return chain.filter(exchange);
}));
}
/**
* 是否需要登录
*
* @param uri 请求URI
* @return boolean
*/
public static boolean needLogin(String uri) {
// test
List<String> uriList = new ArrayList<>();
uriList.add("/api/user/**");
uriList.add("/api/swagger/**");
uriList.add("/api/swagger-ui/**");
uriList.add("/api/api-docs/**");
for (String pattern : uriList) {
if (matcher.match(pattern, uri)) {
// 不需要拦截
return true;
}
}
return false;
}
@Override
public int getOrder() {
return 0;
}
}
过滤器参考:完美解决Spring Cloud Gateway跨域配置不生效问题_gateway跨域配置不起作用-CSDN博客