The IP address displayed on the entire network takes you 5 minutes to add, it’s that simple

Hello everyone, I am Yihang!

Recently, following Sina Weibo, Toutiao, Tencent, Douyin, Zhihu, Kuaishou, Xiaohongshu, Baijiahao and other major platforms have launched the "network user IP address display function" one after another . It is the country and the province displayed for domestic users, and this display cannot be turned off, and the place of origin is forced to be displayed;

As a technical person, then! How to implement this function?

In fact, it is very easy to implement this function. Based on the ready-made GeoLite2 offline library + free online analysis resources, it can be integrated in 5 minutes;

Before integrating, let’s take a brief look at the ways to get the user’s location information:

  • Terminal positioning

    Our mobile phones and other electronic devices all have GPS positioning functions. The APP can apply for permission to obtain the longitude and latitude coordinates of the user. Based on the coordinates, the user's location can be known; for example, map manufacturers such as Baidu and Amap can Provides a complete SDK, which can be easily integrated into applications and quickly obtain detailed location details based on longitude and latitude;

    advantage

    • fast;
    • precise;
    • The error is small.

    shortcoming

    • Depends on hardware support;
    • Relies on user authorization. If the user does not authorize, the APP will not be able to obtain the longitude and latitude information, resulting in failure;
  • IP address acquisition

    The user's request to the server will carry the IP address. After the server obtains the IP address, it can resolve the user's location based on the IP;

    advantage

    • No authorization is required. As long as the user interacts with the server, the server can get the corresponding IP information.

    shortcoming

    • The accuracy is not high and the position may be biased;

    • The IP database is not updated in a timely manner, resulting in failure to resolve the location of some IP addresses.

  • Third-party terminal reporting

    For example, when we ride a shared bicycle, our location information is reported to the server through the bicycle device;

    advantage

    • Reported by third-party terminals based on GPS positioning, personal device information will not be obtained;
    • Accurate and fast;
    • Professional equipment, small error;

    shortcoming

    • The user cannot intervene, the information will be forced to be uploaded to the server, and the user cannot cancel the upload;

Next, let’s try to integrate the GeoLite2 free IP library into the SpringBoot project to obtain the user’s location information;

What is GeoLite2?

The GeoLite2 database is a free IP geolocation database;

advantage:

  • Offline library, no network required
  • Rich database
  • high speed
  • free

shortcoming:

  • The accuracy is not high and there are deviations
  • Data update is slow

Download GeoLite2 offline library

Official website address: https://www.maxmind.com/en/home

The downloading process is a little troublesome. Here is the latest download and put it on the network disk. If you need to test it, you can download it directly through this link: https://www.123pan.com/s/xPY9-J37vH

SpringBoot gets the user's IP

  • Tools

    public class IpUtils {
          
          
        /**
         * 获取用户IP
         * @param request
         * @return
         */
        public static String getIpAddr(HttpServletRequest request) {
          
          
    
            String ip = request.getHeader("x-forwarded-for");
    
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
          
          
                ip = request.getHeader("X-Real-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
          
          
                ip = request.getHeader("http_client_ip");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
          
          
                ip = request.getRemoteAddr();
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
          
          
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
          
          
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
          
          
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
    
            // 如果是多级代理,那么取第一个ip为客户ip
            if (ip != null && ip.indexOf(",") != -1) {
          
          
                ip = ip.substring(ip.lastIndexOf(",") + 1).trim();
            }
            return ip;
        }
    }
    
  • Controller gets HttpServletRequest

    Through the above tool class, you can obtain the real IP requested by the user;

    In order to avoid duplication of work, you can also use AOP to parse the user's IP information and put it in the user's request object.

    @RestController
    public class IpController {
          
          
        @GetMapping("/user/ip")
        public String userIp(HttpServletRequest request) {
          
          
            // 这里就能拿到用户的真实IP
            return IpUtils.getIpAddr(request);
        }
    }
    

SpringBoot integrates GeoLite2

  • Add dependencies

    <dependency>
        <groupId>com.maxmind.geoip2</groupId>
        <artifactId>geoip2</artifactId>
        <version>2.3.0</version>
    </dependency>
    
    <dependency>
        <groupId>com.maxmind.db</groupId>
        <artifactId>maxmind-db</artifactId>
        <version>1.0.0</version>
    </dependency>
    
  • Tools

    public class GeoIpUtils {
          
          
        private static DatabaseReader reader;
    
        private static void init() {
          
          
            try {
          
          
                // 创建 GeoLite2 数据库 Reader
                // 这里可以放在本地磁盘,也可以随项目放在resource目录下
                File database = new File("F:\\web\\GeoLite2-City.mmdb");
                // 读取数据库内容
                reader = new DatabaseReader.Builder(database).build();
            } catch (Exception ex) {
          
          
    
            }
        }
    
        public static void getCityByIP(String ip) throws Exception {
          
          
            if (null == reader) {
          
          
                init();
            }
    
            InetAddress ipAddress = InetAddress.getByName(ip);
    
            // 获取查询结果
            CityResponse response = reader.city(ipAddress);
    
            // 获取国家信息
            Country country = response.getCountry();
            System.out.println("国家信息:" + JSON.toJSONString(country));
    
            // 获取省份
            Subdivision subdivision = response.getMostSpecificSubdivision();
            System.out.println("省份信息:" + JSON.toJSONString(subdivision));
    
            //城市
            City city = response.getCity();
            System.out.println("城市信息:" + JSON.toJSONString(city));
    
            // 获取城市
            Location location = response.getLocation();
            System.out.println("经纬度信息:" + JSON.toJSONString(location));
        }
    }
    
  • test

    public static void main(String[] args) throws Exception {
          
          
        String ip = "183.19.xxx.138";
        GeoIpUtils.getCityByIP(ip);
    }
    

    Output result:

    国家信息:{
          
          "geoNameId":1814991,"isoCode":"CN","name":"China","names":{
          
          "de":"China","ru":"Китай","pt-BR":"China","ja":"中国","en":"China","fr":"Chine","zh-CN":"中国","es":"China"}}
    省份信息:{
          
          "geoNameId":1809935,"isoCode":"GD","name":"Guangdong","names":{
          
          "en":"Guangdong","fr":"Province de Guangdong","zh-CN":"广东"}}
    城市信息:{
          
          "geoNameId":1998011,"name":"Yanqianlaocun","names":{
          
          "en":"Yanqianlaocun","zh-CN":"岩前老村"}}
    经纬度信息:{
          
          "accuracyRadius":500,"latitude":23.3255,"longitude":116.5007,"timeZone":"Asia/Shanghai"}
    

It's that simple. You can easily get detailed information such as the country, province, city, longitude and latitude of the user's IP. You can further encapsulate the data according to your business needs.

Other uses of GeoLite2

As introduced above, SpringBoot integrates GeoLite2. In other scenarios, GeoLite2 can also be used to obtain location information;

  • Integrate into Nignx to obtain user location information

    Nginx integrates GeoLite2 to parse the user's home information, and directly organizes the corresponding data at the proxy layer;

  • Integrating GeoLite2 into ELK

    When sorting ELK logs, you can obtain the user's IP address information through GeoLite2; then through Kibana, you can display the user's geographical distribution very intuitively;

Online program

At the beginning of the introduction to GeoLite2 above, we listed the problem that its offline library is not updated and included in a timely manner, which may cause some IPs to not exist in the offline library. When searching, errors will be reported, as shown in the following example AddressNotFoundException:

What should we do when encountering such a request?

Next, we will introduce several ways to obtain the online IP address. When the local offline library cannot be obtained, you can use the third-party online library to supplement and improve it;

Advantages of getting it online:

  • IP updates in a timely manner
  • High accuracy

shortcoming

  • Strong dependence on three parties
  • You need to pay, and the free version generally has various restrictions.

xxx.xxx.xxx.xxx in the following examples all represent IP addresses;

Baidu

Address: https://opendata.baidu.com/api.php?query=xxx.xxx.xxx.xxx&resource_id=6006&co=&oe=utf8

Response data:

{
    
    
  "status": "0",
  "t": "",
  "set_cache_time": "",
  "data": [
    {
    
    
      "ExtendedLocation": "",
      "OriginQuery": "183.19.xxx.138",
      "appinfo": "",
      "disp_type": 0,
      "fetchkey": "183.19.xxx.138",
      "location": "广东省肇庆市 电信",
      "origip": "183.19.xxx.138",
      "origipquery": "183.19.xxx.138",
      "resourceid": "6006",
      "role_id": 0,
      "shareImage": 1,
      "showLikeShare": 1,
      "showlamp": "1",
      "titlecont": "IP地址查询",
      "tplt": "ip"
    }
  ]
}

Status equals 0 means success, 1 means failure; there may be situations where status equals 0, but there is no data in data.

ip-api interface

  • IP information of this machine

    http://ip-api.com/json/

  • Specify internationalization

    http://ip-api.com/json/?lang=zh-CN

  • Specify IP query

    http://ip-api.com/json/xxx.xxx.xxx.xxx?lang=zh-CN

    Return data:

    {
          
          
      "status": "success",
      "country": "中国",
      "countryCode": "CN",
      "region": "GD",
      "regionName": "广东",
      "city": "岩前老村",
      "zip": "",
      "lat": 23.3255,
      "lon": 116.5007,
      "timezone": "Asia/Shanghai",
      "isp": "Chinanet",
      "org": "Chinanet GD",
      "as": "AS4134 CHINANET-BACKBONE",
      "query": "183.19.xxx.138"
    }
    

Sohu IP query

http://pv.sohu.com/cityjson?ie=utf-8

Return data comparison is simple:

var returnCitySN = {
    
    "cip": "xxx.xxx.xxx.xxx", "cid": "440300", "cname": "广东省深圳市"};

Pacific IP address query

Address: http://whois.pconline.com.cn/ipJson.jsp?ip=xxx.xxx.xxx.xxx&json=true

Return data:

{
    
    
  "ip": "183.17.xxx.138",
  "pro": "广东省",
  "proCode": "440000",
  "city": "深圳市",
  "cityCode": "440300",
  "region": "",
  "regionCode": "0",
  "addr": "广东省深圳市 电信",
  "regionNames": "",
  "err": ""
}

Taobao API interface

http://ip.taobao.com/service/getIpInfo.php?ip=xxx.xxx.xxx.xxx

{
    
    
    "code": 0,
    "data": {
    
    
        "ip": "183.17.xxx.138",
        "country": "中国",
        "area": "",
        "region": "广东",
        "city": "深圳",
        "county": "XX",
        "isp": "电信"
    }
}

code equal to 0 means success, 1 means failure

126

Address: https://ip.ws.126.net/ipquery?ip=xxx.xxx.xxx.xxx

Response data:

var lo="广东省", lc="肇庆市"; 
var localAddress={
    
    city:"肇庆市", province:"广东省"}

The response data is relatively simple

IP information

Address: https://ip.useragentinfo.com/json?ip=xxx.xxx.xxx.xxx

Response data:

{
    
    
  "country": "中国",
  "short_name": "CN",
  "province": "广东省",
  "city": "肇庆市",
  "area": "德庆县",
  "isp": "电信",
  "net": "",
  "ip": "183.19.xxx.138",
  "code": 200,
  "desc": "success"
}

With so many gestures, it is very easy to implement; if you are more dependent on the need for IP resolution, you can also develop a separate IP resolution module as the company's basic service by adding so many online methods offline. , provided for use by other internal modules.

Okay, that’s it for today’s sharing, thank you for your likes, attention, and collections!

Guess you like

Origin blog.csdn.net/lupengfei1009/article/details/124823038