web/node.js

maxmind의 geoLite2를 이용해서 접속한 사용자의 지역정보 가져오기

반응형

서비스를 운영하다보면 사용자 아이피에 따라 장소에 맞는 상품을 추천해줘야 할 때가 있다.

그럴때 사용하는게 geoIp인데 이런 서비스를 제공하는 회사는 대표적으로 maxmind, db-ip, ipstack, ip2location 등이 존재한다.


그 중에 무료로 사용하기에 geoLite2가 좋다. geoLite2는 62%가 일치하고 geoIp2는 66% 일치한 정보를 제공한다. 그래서 무료로 사용할 수 있는 geoLite2를 사용해보자.


데이터베이스 다운로드

먼저 지역정보를 보관하고 있는 데이터베이스를 다운받아야 한다. 데이터베이스는 csv와 mmDB를 제공한다.  

링크 : https://dev.maxmind.com/geoip/geoip2/geolite2/ 


mmDB에서 데이터를 확인하기 어렵기 때문에 csv 파일에서 제공하는 정보를 보자. 우리가 필요한 정보는 사용자가 접속한 city (도시)정보가 필요한데 그 필드가 geoname_id로 되어 있다. 그 geoname_id는 지역에 고유 아이디로 이 아이디에 맞는 city 정보를 찾는 방법은 아래 주소를 통해 xml 형태로 받아 볼 수 있다. username 값은 회원가입을 통해 등록 할 수있다.

1
http://ws.geonames.org/get?geonameId=${geoname_id}&style=full&username=${userName}
cs


그럼 node.js에서 이 데이터베이스와 사용자 ip를 사용하여 city 정보를 추출하는 방법을 확인해보자.


우선 아래 주소에서 maxmind npm을 다운로드 받는다.

https://www.npmjs.com/package/maxmind


그리고 maxmind 라이브러리를 사용해서 데이터베이스를 로드하고 ip를 사용하여 지오로케이션 정보를 조회 할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
'use strict';
 
const maxmind = require('maxmind');
const path = require('path');
 
class MaxMindService {
 
  getIp(userIp) {
    const cityLookUp = maxmind.openSync(path.join(__dirname, './db/GeoLite2-City.mmdb'));
    const city = cityLookUp.get(userIp);
 
    return city;
  }
 
};
 
 
module.exports = new MaxMindService();
cs


테스트 코드를 만들어서 결과를 확인해보자.

1
2
3
4
5
6
7
8
9
10
11
'use strict';
 
const geoIp = require('../../lib/maxMind');
 
 
describe('geo IP', function () {
  it('아이피 정보로 지역정보 찾아보기', () => {
    console.log(geoIp.getIp('121.131.27x.1xx'));
  });
 
});
cs


결과를 보면 ip에 맞는 위치정보가 출력된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
{ city: { geoname_id: 1841277, names: { en: 'Mapo-gu' } },
  continent: 
   { code: 'AS',
     geoname_id: 6255147,
     names: 
      { de: 'Asien',
        en: 'Asia',
        es: 'Asia',
        fr: 'Asie',
        ja: 'アジア',
        'pt-BR''Ásia',
        ru: 'Азия',
        'zh-CN''亚洲' } },
  country: 
   { geoname_id: 1835841,
     iso_code: 'KR',
     names: 
      { de: 'Südkorea',
        en: 'Republic of Korea',
        es: 'Corea del Sur',
        fr: 'Corée du Sud',
        ja: '大韓民国',
        'pt-BR''Coreia do Sul',
        ru: 'Южная Корея',
        'zh-CN''大韩民国' } },
  location: 
   { accuracy_radius: 10,
     latitude: 37.5544,
     longitude: 126.9093,
     time_zone: 'Asia/Seoul' },
  registered_country: 
   { geoname_id: 1835841,
     iso_code: 'KR',
     names: 
      { de: 'Südkorea',
        en: 'Republic of Korea',
        es: 'Corea del Sur',
        fr: 'Corée du Sud',
        ja: '大韓民国',
        'pt-BR''Coreia do Sul',
        ru: 'Южная Корея',
        'zh-CN''大韩民国' } },
  subdivisions: [ { geoname_id: 1835847, iso_code: '11', names: [Object] } ] }
Process finished with exit code 0
 
cs


반응형