GeoIP2, GeoLite2를 사용하여 java에서 ip 접속 국가 정보 확인하는 방법
글로벌 서비스를 운영하는 경우 접속 ip를 통해 국가 정보를 확인해야 하는 경우가 있을 수 있으며, 글로벌 서비스가 아니더라도 해외에서 들어오는 요청을 차단하기 위해 접속 ip에 대한 지역 정보가 필요한 경우가 있습니다.
해당 포스팅은 java에서 client ip를 통해 접속 국가 정보를 확인할 수 있는 api인 'GeoIP2(com.maxmind.geoip2)'와 무료 데이터베이스 'GeoLite2'를 사용하는 방법에 대한 내용입니다.
* 무료 데이터베이스인 GeoLite2와 유로 데이터베이스 GeoIP2는 정확도 측면에서 차이가 있습니다.
GeoLite2 다운로드
아래 예시에서는 GeoLite2를 다운로드하여 적용하는 방법이 사용되는데요. 2018년 이전에는 회원가입 없이 데이터베이스를 다운로드할 수 있었지만, 현재는 회원가입 후 해당 데이터베이스를 받을 수 있습니다.
회원가입 후 'Products' -> 'GeoLite2 Free Geolocation Data' -> 'Download Files'로 이동하면 위 이미지와 같이 다운로드할 수 있는 데이터베이스(GeoLite2 ASN, GeoLite2 City, GeoLite2 Country)를 확인할 수 있는데요.
여기서 'GZIP(.tar.gz)' 파일을 다운로드하면 되며, Country 데이터베이스의 경우 국가별 ip를 분류할 수 있으며, City 데이터베이스의 경우 도시를 기준으로 하여 보다 세분화된 ip 분류를 수행할 수 있습니다.
* ASN(Autonomous System Numbers) 자율 시스템 번호
GeoIP2, GeoLite2 사용 예시 코드
1. 의존성 추가
<!-- https://mvnrepository.com/artifact/com.maxmind.geoip2/geoip2 -->
<dependency>
<groupId>com.maxmind.geoip2</groupId>
<artifactId>geoip2</artifactId>
<version>4.0.1</version>
</dependency>
(Maven 의존성 추가)
// https://mvnrepository.com/artifact/com.maxmind.geoip2/geoip2
implementation group: 'com.maxmind.geoip2', name: 'geoip2', version: '4.0.1'
(Gradle 의존성 추가)
먼저 com.maxmind.geoip2 의존성을 추가해 줍니다.
2. 다운로드한 gzip 파일의 압축을 풀어 프로젝트에서 사용할 수 있게 배치
다음으로 다운로드한 파일의 압축을 풀어 프로젝트에서 사용할 수 있게 배치합니다.
예시의 경우 /resources/data 경로 아래에 배치했으며, maxmind 사이트를 통해 살펴보면 새로운 버전이 올라왔을 때 자동으로 다운로드할 수 있는 방법도 있었습니다.
***
여기서 'mmdb'는 Main Memory Database가 아닌 'MaxMind DB file format'을 뜻하며 IPv4, IPv6 주소를 이진 검색 트리를 사용하여 데이터 레코드에 매핑하는 데이터베이스 형식의 파일을 말합니다.
(더 자세한 내용은 포스팅 하단에 maxmind db에 관한 링크를 첨부해 놓았으니 참고하시면 좋을 것 같습니다.)
3. 데이터베이스를 통해 요청 ip에 대한 지역 정보 확인
@GetMapping("/example/city")
public ResponseEntity<?> getIpInfoFromCityDB(HttpServletRequest request) throws IOException, GeoIp2Exception {
String ip = "{client_ip}";
ClassPathResource resource = new ClassPathResource("data/GeoLite2-City.mmdb");
DatabaseReader databaseReader = new DatabaseReader.Builder(resource.getFile()).build();
InetAddress ipAddress = InetAddress.getByName(ip);
CityResponse response = databaseReader.city(ipAddress);
return ResponseEntity.ok(response);
}
이어서 배치된 GeoLite2-City.mmdb 데이터베이스를 통해 접속 ip에 대한 정보를 받아오는 코드입니다.
com.maxmind.geoip2 package에 정의된 클래스들을 이용하여 상당히 쉽게 구현할 수 있었는데요.
요청 결과 reponse에서는 city_name, country_name, country_iso_code, location, time_zone, ip_address 등의 많은 데이터를 반환받을 수 있으며, 필요한 데이터만 가져와서 사용하면 될 것 같습니다.
//GeoLite2-Country.mmdb 데이터베이스를 사용할 경우
CountryResponse response = databaseReader.country(ipAddress);
//GeoLite2-ASN.mmdb 데이터베이스를 사용할 경우
AsnResponse response = databaseReader.asn(ipAddress);
GeoLite2-City.mmdb 데이터베이스가 아닌 Country, ASN을 사용하는 경우에도 위의 코드처럼 databaseReader 인스턴스에서 호출하는 메서드만 바꿔주면 됩니다.
여기까지 GeoIP2, GeoLite2를 사용하여 ip로부터 지역 정보를 알아보는 방법을 살펴보았는데요.
위 예시의 경우 간단하게 코드 작동만 보기 위해 Controller 단에 코드를 다 넣어놨는데, 아래 github 코드에서는 HttpServletRequest에서 ip를 가져오는 것부터 controller, service 단으로 코드를 나눠놓은 것까지 확인할 수 있으니 필요한 경우 참고하시면 좋을 것 같습니다.
< 관련 자료 >
2022.06.07 - [Programming/Java] - Java 클라이언트 요청 IP 가져오는 방법(HttpServletRequest)
< 참고 자료 >
'Programming > Java' 카테고리의 다른 글
java image resize library 이미지 리사이즈 라이브러리 비교해보기 (0) | 2023.07.15 |
---|---|
Java 8, 11, 17 버전별 추가된 기능 (+ 무슨 버전을 써야할까?) (0) | 2023.07.05 |
Java List null check 방법 (isEmpty, size) (0) | 2023.06.09 |
java stream partitioningBy(), groupingBy() 분할과 그룹화 (0) | 2023.05.24 |
ConcurrentHashMap 개념과 동기화 동작 원리(Thread-safe) (0) | 2023.05.21 |