贵州省建设银行网站,wordpress首页调用文章缩略图,网站页面架构图,修改wordpress wp-adminSpringCloudGateway网关实战#xff08;三#xff09;
上一章节我们讲了gateway的内置过滤器Filter#xff0c;本章节我们来讲讲全局过滤器。
自带全局过滤器
在实现自定义全局过滤器前#xff0c; spring-cloud-starter-gateway依赖本身就自带一些全局过滤器#xff0…SpringCloudGateway网关实战三
上一章节我们讲了gateway的内置过滤器Filter本章节我们来讲讲全局过滤器。
自带全局过滤器
在实现自定义全局过滤器前 spring-cloud-starter-gateway依赖本身就自带一些全局过滤器我们举些比较常用的例子
NettyRoutingFilter该过滤器使用Netty作为底层的HTTP客户端负责将请求转发到下游服务。RouteToRequestUrlFilter该过滤器将根据路由配置中的URI信息将请求转发到指定的URL。WebsocketRoutingFilter该过滤器用于处理WebSocket协议的请求转发。GatewayMetricsFilter该过滤器用于收集网关的基本性能指标数据例如请求的数量、响应时间等。
自定义全局过滤器
自定义全局过滤器需要实现GlobalFilter接口和Ordered接口。
AuthFilter
token验证全局过滤器
引入依赖 !-- Jwt --dependencygroupIdio.jsonwebtoken/groupIdartifactIdjjwt/artifactIdversion0.9.1/version/dependency具体代码
Component
public class AuthFilter implements GlobalFilter, Ordered {private static final Logger log LoggerFactory.getLogger(AuthFilter.class);Autowiredprivate IgnoreWhiteProperties ignoreWhite;Autowiredpublic RedisTemplate redisTemplate;Overridepublic MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) {ServerHttpRequest request exchange.getRequest();ServerHttpRequest.Builder mutate request.mutate();// 跳过白名单String url request.getURI().getPath();if (com.smallred.gateway.utils.StringUtils.matches(url, ignoreWhite.getWhites())) {return chain.filter(exchange);}// 检查令牌是否存在String token getToken(request);if (StringUtils.isEmpty(token)) {return unauthorizedResponse(exchange, 令牌不能为空!);}//Claims claims JwtUtils.parseToken(token);if (claims null) {return unauthorizedResponse(exchange, 令牌已过期或验证不正确);}// 判断登录状态String userKey JwtUtils.getUserKey(claims);Boolean islogin redisTemplate.hasKey(getTokenKey(userKey));if (!islogin) {return unauthorizedResponse(exchange, 登录状态已过期!);}// 验证用户信息String userId JwtUtils.getUserId(claims);String userName JwtUtils.getUserName(claims);if (StringUtils.isEmpty(userId) || StringUtils.isEmpty(userName)) {return unauthorizedResponse(exchange, 令牌验证失败);}// 设置用户信息到请求addHeader(mutate, user_key, userKey);addHeader(mutate, user_id, userId);addHeader(mutate, username, userName);// 内部请求来源参数清除removeHeader(mutate, from-source);return chain.filter(exchange.mutate().request(mutate.build()).build());}/*** 添加头*/private void addHeader(ServerHttpRequest.Builder mutate, String name, Object value) {if (value null) {return;}String valueStr value.toString();String valueEncode urlEncode(valueStr);mutate.header(name, valueEncode);}/*** 删除头*/private void removeHeader(ServerHttpRequest.Builder mutate, String name) {mutate.headers(httpHeaders - httpHeaders.remove(name)).build();}/*** 获取缓存key*/private String getTokenKey(String token) {return login_tokens: token;}/*** 获取请求token*/private String getToken(ServerHttpRequest request) {String token request.getHeaders().getFirst(Authorization);// 如果前端设置了令牌前缀则裁剪掉前缀if (StringUtils.isNotEmpty(token) token.startsWith(Bearer)) {token token.replaceFirst(Bearer, StringUtils.EMPTY);}return token;}/*** 内容编码** param str 内容* return 编码后的内容*/public static String urlEncode(String str){try{return URLEncoder.encode(str, UTF-8);}catch (UnsupportedEncodingException e){return StringUtils.EMPTY;}}/*** 验证失败返回*/private MonoVoid unauthorizedResponse(ServerWebExchange exchange, String msg) {log.error([鉴权异常处理]请求路径:{}, exchange.getRequest().getPath());return ServletUtils.webFluxResponseWriter(exchange.getResponse(), msg, 401);}Overridepublic int getOrder() {return -200;}
}依赖类
白名单
Configuration
RefreshScope
ConfigurationProperties(prefix security.ignore)
public class IgnoreWhiteProperties {private ListString whites new ArrayList();public ListString getWhites() {return whites;}public void setWhites(ListString whites) {this.whites whites;}
}白名单配置
# 安全配置
security:ignore:whites:- /auth/logout- /auth/login- /auth/register- /*/v2/api-docs- /csrfStringUtils类
public class StringUtils {/** 空字符串 */private static final String NULLSTR ;public static boolean matches(String str, ListString strs){if (isEmpty(str) || isEmpty(strs)){return false;}for (String pattern : strs){if (isMatch(pattern, str)){return true;}}return false;}public static boolean isEmpty(String str){return isNull(str) || NULLSTR.equals(str.trim());}public static boolean isEmpty(Collection? coll){return isNull(coll) || coll.isEmpty();}public static boolean isNull(Object object){return object null;}public static boolean isMatch(String pattern, String url){AntPathMatcher matcher new AntPathMatcher();return matcher.match(pattern, url);}}ServletUtils类
public class ServletUtils {public static MonoVoid webFluxResponseWriter(ServerHttpResponse response, Object value, int code){return webFluxResponseWriter(response, HttpStatus.OK, value, code);}public static MonoVoid webFluxResponseWriter(ServerHttpResponse response, HttpStatus status, Object value, int code){return webFluxResponseWriter(response, MediaType.APPLICATION_JSON_VALUE, status, value, code);}public static MonoVoid webFluxResponseWriter(ServerHttpResponse response, String contentType, HttpStatus status, Object value, int code){response.setStatusCode(status);response.getHeaders().add(HttpHeaders.CONTENT_TYPE, contentType);R? result R.fail(code, value.toString());DataBuffer dataBuffer response.bufferFactory().wrap(JSON.toJSONString(result).getBytes());return response.writeWith(Mono.just(dataBuffer));}}JwtUtils类
public class JwtUtils {public static String secret abcdefghijklmnopqrstuvwxyz;/*** 从数据声明生成令牌** param claims 数据声明* return 令牌*/public static String createToken(MapString, Object claims){String token Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS512, secret).compact();return token;}/*** 从令牌中获取数据声明** param token 令牌* return 数据声明*/public static Claims parseToken(String token){return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();}/*** 根据令牌获取用户标识** param token 令牌* return 用户ID*/public static String getUserKey(String token){Claims claims parseToken(token);return getValue(claims, user_key);}/*** 根据令牌获取用户标识** param claims 身份信息* return 用户ID*/public static String getUserKey(Claims claims){return getValue(claims, user_key);}/*** 根据令牌获取用户ID** param token 令牌* return 用户ID*/public static String getUserId(String token){Claims claims parseToken(token);return getValue(claims, user_id);}/*** 根据身份信息获取用户ID** param claims 身份信息* return 用户ID*/public static String getUserId(Claims claims){return getValue(claims, user_id);}/*** 根据令牌获取用户名** param token 令牌* return 用户名*/public static String getUserName(String token){Claims claims parseToken(token);return getValue(claims, username);}/*** 根据身份信息获取用户名** param claims 身份信息* return 用户名*/public static String getUserName(Claims claims){return getValue(claims, username);}/*** 根据身份信息获取键值** param claims 身份信息* param key 键* return 值*/public static String getValue(Claims claims, String key){return toStr(claims.get(key), );}public static String toStr(Object value, String defaultValue){if (null value){return defaultValue;}if (value instanceof String){return (String) value;}return value.toString();}}IpAddressFilter
根据请求记录ip地址日志
Component
public class IpAddressFilter implements GlobalFilter, Ordered {public static final MapString, AtomicInteger CACHE new ConcurrentHashMap();Overridepublic MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) {InetSocketAddress host exchange.getRequest().getHeaders().getHost();if (host null || host.getHostName() null) {exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);return exchange.getResponse().setComplete();}String hostName host.getHostName();AtomicInteger count CACHE.getOrDefault(hostName, new AtomicInteger(0));count.incrementAndGet();CACHE.put(hostName, count);System.out.println(IP地址 hostName ,访问次数 count.intValue());return chain.filter(exchange);}Overridepublic int getOrder() {return 101;}
}