250x250
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 자동배포
- spring
- apache.poi
- Jenkins
- JPA
- sqlserver
- ci/cd
- DevOps
- Stream
- 보안
- MessageQueue
- QueryDSL
- 대용량 업로드
- 그리드
- 엑셀 업로드
- docker
- ORM
- 자바8
- Javascript
- 스트림
- rabbitmq
- 제이쿼리그리드
- 자동빌드
- jqGrid
- stream api
- JQuery
- mom
- mssql
- java
- poi
Archives
- Today
- Total
개발 메모장
[Java] 공공데이터 - IP 확인 API 사용하기 본문
728x90
#. 보안과 관련하여 해외에서 접속하는 IP에 대한 점검을 해야할 필요성을 느꼈습니다.
#. 해외 IP를 확인하는 방법은 외부 라이브러리, 정부 제공 API 등 처리방법이 있습니다.
#. 서비스 중인 프로젝트는 특정된 대상만이 사용하도록 되어있기에 더더욱 해외에서 접속할 일은 없기 때문에 아래와 같이 정부 제공 API를 적용하였습니다.
#. 이는 일일 트래픽 10,000건까지만 제공하므로 더 필요한 경우 웹사이트에 따라 증가시키길 바랍니다.
#. API 사용하기
- 참고문서를 다운받아 필요한 내용에 대한 API URL을 확인합니다.
- 아래와 같이 목록에서 원하는 내용을 선택한 뒤 활용신청 버튼을 눌러 API KEY를 발급받습니다.

- 요청하는 값을 넣어 처리해보면 아래와 같이 데이터를 리턴 받습니다.

- 사이트 접속은 클릭 또는 하단을 참고해주시길 바랍니다.
#. 구현하기 - Java Script
- 처음엔 HttpServletRequest > getRemoteAddr 메서드를 이용해 보았으나 내부 IP를 사용하는 경우 국가코드가 해외로 확인되는 경우가 있었습니다.
- 정확한 확인을 위해선 공인 IP를 호출하여 체크 해야 했고 아래와 같이 구현하였습니다.
- 자바스크립트를 이용해 공인IP 확인이 가능한 url을 Fetch에 넣어 값을 응답받고 핸들러로 보내 처리하는 방법입니다.
- 접속 시 공인 IP를 확인할 수 있는 웹사이트를 참고하시길 바랍니다.
function fetchPublicIPAndSubmit() {
fetch('https://checkip.amazonaws.com') //https://api64.ipify.org
.then(response => response.text())
.then(ip => {
ip = ip.trim();
if ($('#client_ip').length === 0) {
$('<input>').attr({
type: 'hidden',
id: 'client_ip',
name: 'client_ip',
value: ip
}).appendTo('form');
} else {
$('#client_ip').val(ip);
}
})
.catch(error => {
console.error('IP 호출 실패 : ', error);
})
.finally(() => {
// IP 호출 실패해도 로그인 폼 제출 진행
submitLoginForm();
});
}
function submitLoginForm() {
var url = '<c:out value="${url}" />';
$("form").attr("action", url);
$("form").submit();
}
- 해당 웹사이트로 연결해서 응답을 받고 그 값을 hidden 태그에 넣어 form을 보낼 때 함께 보내는 방법입니다.
#. 구현하기 - Handler
- 로그인 페이지에서 아래와 같이 AuthenticationSuccessHandler를 상속받아 처리하는 메서드를 만들어줍니다.
- NONE을 KR과 함께 넣은 이유는 127.0.0.1이나 가상IP의 경우 국가코드가 NONE으로 나오기 때문에 그렇습니다.
- 분기에 통과되지 못하면 로그를 만드는 메서드로 넘어가 로그파일을 떨구는 방식으로 만들었으니 해당 부분은 원하는 방법에 맞게 처리하시면 됩니다. (로그 생성, 로그파일 만들기, 첫 페이지로 이동 등)
public class LoginSuccessHandler implements AuthenticationSuccessHandler {
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
String publicIp = request.getParameter("client_ip");
ipChecker(publicIp);
}
private void ipChecker(String ip) throws IOException {
User user = SecurityUtils.getUser();
StringBuilder urlBuilder = new StringBuilder("http://apis.data.go.kr/B551505/whois/ip_address"); // URL
urlBuilder.append("?" + URLEncoder.encode("serviceKey","UTF-8") + "발급받은 키");
urlBuilder.append("&" + URLEncoder.encode("query","UTF-8") + "=" + ip);
urlBuilder.append("&" + URLEncoder.encode("answer","UTF-8") + "=" + URLEncoder.encode("json", "UTF-8")); // 응답형식(XML/JSON) 을 지정(없으면 XML으로 응답)
URL url = new URL(urlBuilder.toString());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Content-type", "application/json");
BufferedReader rd;
if(conn.getResponseCode() >= 200 && conn.getResponseCode() <= 300) {
rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
} else {
rd = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
System.out.println("API 호출 실패 (응답 코드: " + conn.getResponseCode() + ")");
return;
}
StringBuilder sb = new StringBuilder();
String line;
while ((line = rd.readLine()) != null) {
sb.append(line);
}
rd.close();
conn.disconnect();
try {
JSONParser parser = new JSONParser();
JSONObject jsonObj = (JSONObject) parser.parse(sb.toString());
JSONObject response = (JSONObject) jsonObj.get("response");
JSONObject whoIs = (JSONObject) response.get("whois");
String countryCode = (String) whoIs.get("countryCode");
if(!"KR".equals(countryCode) && !"NONE".equals(countryCode)) {
CreateLogFile.createLog(user.getUserId(), "strange_IP", "");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
#. 로그 파일을 생성하는 메서드를 통해 아래와 같이 생성된 것을 확인할 수 있습니다.

===========================================================
틀린 내용이 있거나 이견 있으시면 언제든 가감 없이 말씀 부탁드립니다!
참조 : https://www.data.go.kr/data/15094277/openapi.do
===========================================================
728x90
'Java' 카테고리의 다른 글
[Java] HTTPS 통신 시 인증서 관련 오류(DH keypair) (1) | 2024.11.05 |
---|---|
[Java] 함수형 인터페이스(Functional Interface) (0) | 2024.06.13 |
[Java] keytool을 이용한 루트 인증서 등록(SSLHandshakeException) (0) | 2024.04.18 |
[Java] Apache.POI 엑셀 업로드 구현 - DB 처리(3/3) (1) | 2024.01.05 |
[Java] Apache.POI 엑셀 업로드 구현 - Controller(2/3) (2) | 2024.01.04 |