1: 创建过滤器类
首先,你需要创建一个实现了
GatewayFilter
接口或者继承AbstractGatewayFilterFactory
类的过滤器类。这里以实现GatewayFilter
接口为例,创建一个全局token过滤器。
package com.by.filter;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.jwt.JWTValidator;
import cn.hutool.jwt.signers.JWTSignerUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.net.URI;
import java.util.List;
@Slf4j
//@Component
public class TokenFilter implements GlobalFilter {
@Value("${cn.loong.tokenx.key}")
private String tokenKey;
private static List<String> whiteList = CollUtil.newArrayList("/api/login", "/api/register");
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
URI uri = request.getURI();
String path = uri.getPath().toLowerCase().trim();
//排除白名单的验证
if(whiteList.contains(path)){
return chain.filter(exchange);
}
ServerHttpResponse response = exchange.getResponse();
// 获取请求头
List<String> tokens = request.getHeaders().get("token");
// 判断是否传了token
if(ObjectUtil.isEmpty(tokens)){
log.error("token为空,请传token");
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
String token = tokens.get(0);
// 判断token是否合法
if (ObjectUtil.isEmpty(token)){
log.error("token不能为空");
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
boolean b = false;
//判断token是否有效
// 验证算法 包含过期时间
try {
JWTValidator.of(token).validateAlgorithm(JWTSignerUtil.hs256(tokenKey.getBytes())).validateDate();
b = true;
}catch (Exception e){
e.printStackTrace();
log.error("token无效");
}
if (!b){
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
// 放行
return chain.filter(exchange);
}
}
2: 注册全局过滤器
为了让Spring Cloud Gateway应用识别并使用这个过滤器,你通常需要在配置类中注册它。但是,由于我们使用了@Component注解,Spring会自动扫描并注册该Bean。
使用@Component或下面代码,二选一。
@Configuration
public class FilterConfig {
@Bean
public TokenFilter tokenFilter() {
return new TokenFilter();
}
}