diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/ServerWebExchangeUtil.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/ServerWebExchangeUtil.java index 3446be1f..88634b27 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/ServerWebExchangeUtil.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/ServerWebExchangeUtil.java @@ -30,6 +30,8 @@ import reactor.core.publisher.Mono; import javax.servlet.http.HttpServletRequest; import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.List; @@ -47,6 +49,10 @@ public class ServerWebExchangeUtil { private static final String UNKNOWN_PATH = "/sop/unknown"; private static final String REST_PATH = "/rest"; + private static final String IP_UNKNOWN = "unknown"; + private static final String IP_LOCAL = "127.0.0.1"; + private static final int IP_LEN = 15; + private static FormHttpMessageConverter formHttpMessageConverter = new FormHttpMessageConverter(); private static final List> messageReaders; @@ -111,21 +117,31 @@ public class ServerWebExchangeUtil { return chain.filter(newExchange); } - public static ApiParam getApiParam(ServerWebExchange exchange, String body) { + public static ApiParam getApiParamByQuery(ServerWebExchange exchange, String query) { + ApiParam apiParam = new ApiParam(); + String ip = getIP(exchange.getRequest()); + apiParam.setIp(ip); + Map params = RequestUtil.parseQueryToMap(query); + if (params != null) { + apiParam.putAll(params); + } + setApiParam(exchange, apiParam); + return apiParam; + } + + public static ApiParam getApiParam(ServerWebExchange exchange, byte[] body) { MediaType contentType = exchange.getRequest().getHeaders().getContentType(); if (contentType == null) { contentType = MediaType.APPLICATION_FORM_URLENCODED; } ApiParam apiParam = new ApiParam(); - String ip = Optional.ofNullable(exchange.getRequest().getRemoteAddress()) - .map(address -> address.getAddress().getHostAddress()) - .orElse(""); + String ip = getIP(exchange.getRequest()); apiParam.setIp(ip); Map params = null; String contentTypeStr = contentType.toString().toLowerCase(); // 如果是json方式提交 if (StringUtils.containsAny(contentTypeStr, "json", "text")) { - JSONObject jsonObject = JSON.parseObject(body); + JSONObject jsonObject = JSON.parseObject(new String(body, SopConstants.CHARSET_UTF8)); apiParam.putAll(jsonObject); } else if (StringUtils.containsIgnoreCase(contentTypeStr, "multipart")) { // 如果是文件上传请求 @@ -136,7 +152,7 @@ public class ServerWebExchangeUtil { apiParam.setUploadContext(uploadInfo.getUploadContext()); } else { // APPLICATION_FORM_URLENCODED请求 - params = RequestUtil.parseQueryToMap(body); + params = RequestUtil.parseQueryToMap(new String(body, SopConstants.CHARSET_UTF8)); } if (params != null) { apiParam.putAll(params); @@ -145,6 +161,45 @@ public class ServerWebExchangeUtil { return apiParam; } + /** + * 获取客户端真实ip + * @param request request + * @return 返回ip + */ + public static String getIP(ServerHttpRequest request) { + HttpHeaders headers = request.getHeaders(); + String ipAddress = headers.getFirst("x-forwarded-for"); + if (ipAddress == null || ipAddress.length() == 0 || IP_UNKNOWN.equalsIgnoreCase(ipAddress)) { + ipAddress = headers.getFirst("Proxy-Client-IP"); + } + if (ipAddress == null || ipAddress.length() == 0 || IP_UNKNOWN.equalsIgnoreCase(ipAddress)) { + ipAddress = headers.getFirst("WL-Proxy-Client-IP"); + } + if (ipAddress == null || ipAddress.length() == 0 || IP_UNKNOWN.equalsIgnoreCase(ipAddress)) { + ipAddress = Optional.ofNullable(request.getRemoteAddress()) + .map(address -> address.getAddress().getHostAddress()) + .orElse(""); + if (IP_LOCAL.equals(ipAddress)) { + // 根据网卡取本机配置的IP + try { + InetAddress inet = InetAddress.getLocalHost(); + ipAddress = inet.getHostAddress(); + } catch (UnknownHostException e) { + // ignore + } + } + } + + // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割 + if (ipAddress != null && ipAddress.length() > IP_LEN) { + int index = ipAddress.indexOf(","); + if (index > 0) { + ipAddress = ipAddress.substring(0, index); + } + } + return ipAddress; + } + public static ApiParam getApiParam(ServerWebExchange exchange, Map params) { ApiParam apiParam = new ApiParam(); apiParam.putAll(params); @@ -204,11 +259,10 @@ public class ServerWebExchangeUtil { * 获取一个文件上传request * * @param exchange 当前ServerWebExchange - * @param requestBody 上传文件请求体内容 + * @param data 上传文件请求体内容 * @return 返回文件上传request */ - public static HttpServletRequest getFileUploadRequest(ServerWebExchange exchange, String requestBody) { - byte[] data = requestBody.getBytes(StandardCharsets.UTF_8); + public static HttpServletRequest getFileUploadRequest(ServerWebExchange exchange, byte[] data) { return new FileUploadHttpServletRequest(exchange.getRequest(), data); } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/filter/IndexFilter.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/filter/IndexFilter.java index 4e6f6654..64a9d4ae 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/filter/IndexFilter.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/filter/IndexFilter.java @@ -82,9 +82,8 @@ public class IndexFilter implements WebFilter { // 读取请求体中的内容 Mono modifiedBody = serverRequest.bodyToMono(byte[].class) .flatMap(data -> { - String body = new String(data, SopConstants.CHARSET_UTF8); // 构建ApiParam - ApiParam apiParam = ServerWebExchangeUtil.getApiParam(exchange, body); + ApiParam apiParam = ServerWebExchangeUtil.getApiParam(exchange, data); // 签名验证 doValidate(exchange, apiParam); return Mono.just(data); @@ -113,7 +112,7 @@ public class IndexFilter implements WebFilter { // 原始参数 String originalQuery = uri.getRawQuery(); // 构建ApiParam - ApiParam apiParam = ServerWebExchangeUtil.getApiParam(exchange, originalQuery); + ApiParam apiParam = ServerWebExchangeUtil.getApiParamByQuery(exchange, originalQuery); // 签名验证 doValidate(exchange, apiParam);