diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/NetUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/NetUtils.java
new file mode 100644
index 000000000..72fdf4033
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/NetUtils.java
@@ -0,0 +1,84 @@
+package org.dromara.common.core.utils;
+
+import cn.hutool.core.lang.PatternPool;
+import cn.hutool.core.net.NetUtil;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.utils.regex.RegexUtils;
+
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * 增强网络相关工具类
+ *
+ * @author 秋辞未寒
+ */
+@Slf4j
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class NetUtils extends NetUtil {
+
+ /**
+ * 判断是否为IPv6地址
+ *
+ * @param ip IP地址
+ * @return 是否为IPv6地址
+ */
+ public static boolean isIPv6(String ip) {
+ try {
+ // 判断是否为IPv6地址
+ return InetAddress.getByName(ip) instanceof Inet6Address;
+ } catch (UnknownHostException e) {
+ return false;
+ }
+ }
+
+ /**
+ * 判断IPv6地址是否为内网地址
+ *
+ * 以下地址将归类为本地地址,如有业务场景有需要,请根据需求自行处理:
+ *
+ * 通配符地址 0:0:0:0:0:0:0:0 + * 链路本地地址 fe80::/10 + * 唯一本地地址 fec0::/10 + * 环回地址 ::1 + *+ * + * @param ip IP地址 + * @return 是否为内网地址 + */ + public static boolean isInnerIPv6(String ip) { + try { + // 判断是否为IPv6地址 + if (InetAddress.getByName(ip) instanceof Inet6Address inet6Address) { + // isAnyLocalAddress 判断是否为通配符地址,通常不会将其视为内网地址,根据业务场景自行处理判断 + // isLinkLocalAddress 判断是否为链路本地地址,通常不算内网地址,是否划分归属于内网需要根据业务场景自行处理判断 + // isLoopbackAddress 判断是否为环回地址,与IPv4的 127.0.0.1 同理,用于表示本机 + // isSiteLocalAddress 判断是否为本地站点地址,IPv6唯一本地地址(Unique Local Addresses,简称ULA) + if (inet6Address.isAnyLocalAddress() + || inet6Address.isLinkLocalAddress() + || inet6Address.isLoopbackAddress() + || inet6Address.isSiteLocalAddress()) { + return true; + } + } + } catch (UnknownHostException e) { + // 注意,isInnerIPv6方法和isIPv6方法的适用范围不同,所以此处不能忽略其异常信息。 + throw new IllegalArgumentException("Invalid IPv6 address!", e); + } + return false; + } + + /** + * 判断是否为IPv4地址 + * + * @param ip IP地址 + * @return 是否为IPv4地址 + */ + public static boolean isIPv4(String ip) { + return RegexUtils.isMatch(PatternPool.IPV4, ip); + } + +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ip/AddressUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ip/AddressUtils.java index 3f7cd57a9..2878078f1 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ip/AddressUtils.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ip/AddressUtils.java @@ -1,11 +1,11 @@ package org.dromara.common.core.utils.ip; -import cn.hutool.core.net.NetUtil; import cn.hutool.http.HtmlUtil; -import org.dromara.common.core.utils.StringUtils; import lombok.AccessLevel; import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.utils.NetUtils; +import org.dromara.common.core.utils.StringUtils; /** * 获取地址类 @@ -20,14 +20,17 @@ public class AddressUtils { public static final String UNKNOWN = "XX XX"; public static String getRealAddressByIP(String ip) { - if (StringUtils.isBlank(ip)) { + // 处理空串并过滤HTML标签 + ip = HtmlUtil.cleanHtmlTag(StringUtils.blankToDefault(ip,"")); + // 判断是否为IPv4或IPv6,如果不是则返回未知地址 + if (!NetUtils.isIPv4(ip) && !NetUtils.isIPv6(ip)) { return UNKNOWN; } // 内网不查询 - ip = StringUtils.contains(ip, "0:0:0:0:0:0:0:1") ? "127.0.0.1" : HtmlUtil.cleanHtmlTag(ip); - if (NetUtil.isInnerIP(ip)) { + if (NetUtils.isInnerIPv6(ip) || NetUtils.isInnerIP(ip)) { return "内网IP"; } return RegionUtils.getCityInfo(ip); } + }