@TOC
近年来,依据《国家互联网用户账号名称信息管理规定》要求互联网用户账号服务平台标注IP地址属地信息,微信公众号、抖音、知乎各大平台纷纷都上线了IP归属地的性能。本文就带大家实现该性能,国内的用户准确到省份,国外用户准确到国家。
实现原理那么如何依据IP地址查找到具体的归属地信息呢?答案是:通过 自治零碎(Autonomous System)。
互联网是由不同网络组成的网络,自治零碎是组成 Internet 的大型网络,连贯到 Internet 的每台计算机或设施都连贯到一个 AS。而每一个自治零碎都会有一个编码,咱们称之为 ASN。能够认为 AS 相似于一个城镇的邮局。
邮件从一个邮局到另一个邮局,直到达到正确的城镇为止,而后该城镇的邮局将在该城镇内传递邮件。每个 AS 都管制一组特定的 IP 地址,就像每个镇的邮局负责将邮件传递到该镇内的所有地址一样。
通常,每个 AS 由单个大型组织(例如 Internet 服务提供商(ISP)、大型企业技术公司、大学或政府机构)经营。
到这里,咱们能够捋分明这样一个逻辑关系:IP地址 -> 地址块 -> 自治网络编码(ASN) -> 组织 -> 国家。
通过 IP 地址,咱们就能够定位到一个大抵的地理位置,例如:北京朝阳区、深圳南山区等。例如我当初的 IP 地址就归属于编码为 AS4xxx 这个自治网络,通过这个 ASN 能够晓得地位在中国深圳,这个 ASN 编码所属的组织为 中国电信。
然而,要实现这样一个查找性能,首先得要有一个IP地址归属地数据库。网上找了下,以前淘宝网有一个开源的接口API开源调用,但不晓得为何,近一两年,该接口地址曾经下线不能应用了。咱们能够通过调用昂焱数据平台提供的IP地址归属地接口来实现此性能。IP地址归属地查问次要针对以后理论使用最多的IPv4地址,依据IP地址查问其归属地。IP地址归属地查问实用于网络定位、网络跟踪、网络排查等相干场景。
获取IP地址首先,须要获取客户端IP地址
获取IP地址办法:
/** * 获取IP地址 * * 应用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址 * 如果应用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的无效IP字符串,则为实在IP地址 */ public static String getIpAddr(HttpServletRequest request) { String ip = null; try { ip = request.getHeader("x-forwarded-for"); if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_CLIENT_IP"); } if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_X_FORWARDED_FOR"); } if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } } catch (Exception e) { logger.error("IPUtils ERROR ", e); } return ip; }调用IP归属地接口:public class Test{ // 申请的昂焱数据IP归属地接口地址 public static final String URL = "https://www.ayshuju.com/data/ip/address"; // 申请的密钥 public static final String APPKEY = "申请的密钥"; // 申请客户端 public static OkHttpClient client = new OkHttpClient(); public static void main(String[] args) throws IOException { RequestBody formBody = new FormBody.Builder() .add("appKey", APPKEY) .add("ip", "117.186.0.233") .build(); // 执行post申请 String result = doPostByFormData(URL, formBody); System.out.println(result); } /** * @param url url * @throws IOException */ public static String doPostByFormData(String url, RequestBody body) throws IOException { Request request = new Request.Builder().url(url).post(body).build(); try (Response response = client.newCall(request).execute()) { return response.body().string(); } }}更多开发API及代码工具请拜访【昂焱数据平台】
...