2022.01.24 TIL

서승원·2022년 1월 24일
0

TIL

목록 보기
58/68

CAPTCHA를 이용한 예제

CAPTCHA를 이용해서 회원가입시 입력하게 되는 보안문구 이미지 입력 시스템 예제를 만들어봤다.

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
@Override
    protected void service(HttpServletRequest request, 
            HttpServletResponse response) throws ServletException, IOException {
        String clientId = "clientID";//애플리케이션 클라이언트 아이디값";
        String clientSecret = "clientSecret";//애플리케이션 클라이언트 시크릿값";
        String key = "";
        String tempname= "";
        try {
            String code = "0"// 키 발급시 0,  캡차 이미지 비교시 1로 세팅
            String apiURL = "https://naveropenapi.apigw.ntruss.com/captcha/v1/nkey?code=" + code;
            URL url = new URL(apiURL);
            HttpURLConnection con = (HttpURLConnection)url.openConnection();
            con.setRequestMethod("GET");
            con.setRequestProperty("X-NCP-APIGW-API-KEY-ID", clientId);
            con.setRequestProperty("X-NCP-APIGW-API-KEY", clientSecret);
            int responseCode = con.getResponseCode();
            BufferedReader br;
            if(responseCode==200) { // 정상 호출
                br = new BufferedReader(new InputStreamReader(con.getInputStream()));
            } else {  // 오류 발생
                br = new BufferedReader(new InputStreamReader(con.getErrorStream()));
            }
            String inputLine;
            StringBuffer sb = new StringBuffer();
            while ((inputLine = br.readLine()) != null) {
                sb.append(inputLine);
            }
            br.close();
            JSONObject jo = new JSONObject( sb.toString() );
            key = jo.getString( "key" );
            
            
        } catch (Exception e) {
            System.out.println(e);
        }
cs

NAVER CLOUD에서 제공하는 매뉴얼 예제를 이용해서 HttpServlet을 extends 받은 Test909.java의 service 함수에 해당 api를 이용해서 CAPTCHA로부터 key값을 받는 부분이다.apiURL에 접속해서 ID와 Secret Code를 입력하면 key값을 받게 되고, 해당 api로부터 key값을 BufferedReader를 이용해 readLine으로 StringBuffer sb에 입력한다. 해당 json형태로 입력된 sb로부터 key값을 받기 위해 JSONObject로 생성하고, getString으로 key값을 받은 뒤

1
2
3
 request.setAttribute("key", key );
        RequestDispatcher rd = request.getRequestDispatcher("/WEB-INF/test_909_1.jsp");
        rd.forward(request, response);
cs

위와 같은 jsp 파일로 넘겨주는 코드를 작성했다.
jsp 파일에 EL을 이용해 ${key} 로 해당 key 값을 확인하는 테스트를 한 후, key값을 API에 입력해 다시금 이미지를 얻어와 저장하고, 브라우저에 출력한다.

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
try {
            
            String apiURL = "https://naveropenapi.apigw.ntruss.com/captcha-bin/v1/ncaptcha?key=" + key + "&X-NCP-APIGW-API-KEY-ID" + clientId;
            URL url = new URL(apiURL);
            HttpURLConnection con = (HttpURLConnection)url.openConnection();
            con.setRequestMethod("GET");
            int responseCode = con.getResponseCode();
            BufferedReader br;
            if(responseCode==200) { // 정상 호출
                InputStream is = con.getInputStream();
                int read = 0;
                byte[] bytes = new byte[1024];
                // 랜덤한 이름으로 파일 생성
                tempname = Long.valueOf(new Date().getTime()).toString();
                File f = new File(Util.upload() + tempname + ".jpg");
                f.createNewFile();
                OutputStream outputStream = new FileOutputStream(f);
                while ((read =is.read(bytes)) != -1) {
                    outputStream.write(bytes, 0, read);
                }
                is.close();
            } else {  // 오류 발생
                br = new BufferedReader(new InputStreamReader(con.getErrorStream()));
                String inputLine;
                StringBuffer sb = new StringBuffer();
                while ((inputLine = br.readLine()) != null) {
                    sb.append(inputLine);
                }
                br.close();
                
            }
        } catch (Exception e) {
            System.out.println(e);
        }
cs

Test909.java 의 다음 부분에 위와 같은 코드를 작성한다. tempname 변수에 java.Util.Date 로부터 난수를 생성해 파일 이름을 지정하고, upload 폴더에 저장하기 위해 FileOutputStream 을 생성해 해당 이미지를 저장한 뒤
request.setAttribute("fname", tempname );
으로 jsp 파일에 파일의 이름 역시 넘겨준다.

1
2
3
4
5
6
7
8
<img src="image.jsp?fname=${fname}"/>
    <br/>
    
    <form method="POST" action="test910">
        <input type="hidden" name="key" value="${key}"/>
        <input type="text" name="captcha"/>
        <input type="submit"/>
    </form>
cs

jsp파일에 위와 같은 부분을 추가해 해당 파일로부터 CAPTCHA 이미지를 추가한다. 그리고 해당 이미지로부터 판별을 위한 form을 추가한다. 검증을 위한 Test910.java 파일 역시 필요할 것이다.

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
public class Test910 extends HttpServlet {
    boolean success = false;    
    @Override
    protected void doPost(HttpServletRequest request, 
            HttpServletResponse response ) throws ServletException, IOException {
         String clientId = "";//애플리케이션 클라이언트 아이디값";
         String clientSecret = "";//애플리케이션 클라이언트 시크릿값";
            try {
                String code = "1"// 키 발급시 0,  캡차 이미지 비교시 1로 세팅
                String key = request.getParameter("key");
                String captcha = request.getParameter("captcha");
                String apiURL = "https://naveropenapi.apigw.ntruss.com/captcha/v1/nkey?code=" + code +"&key="+ key + "&value="+ captcha;
 
                URL url = new URL(apiURL);
                HttpURLConnection con = (HttpURLConnection)url.openConnection();
                con.setRequestMethod("GET");
                con.setRequestProperty("X-NCP-APIGW-API-KEY-ID", clientId);
                con.setRequestProperty("X-NCP-APIGW-API-KEY", clientSecret);
                int responseCode = con.getResponseCode();
                BufferedReader br;
                if(responseCode==200) { // 정상 호출
                    br = new BufferedReader(new InputStreamReader(con.getInputStream()));
                } else {  // 오류 발생
                    br = new BufferedReader(new InputStreamReader(con.getErrorStream()));
                }
                String inputLine;
                StringBuffer sb = new StringBuffer();
                while ((inputLine = br.readLine()) != null) {
                    sb.append(inputLine);
                }
                br.close();
                JSONObject jo = new JSONObject( sb.toString() );
                success = jo.getBoolean("result");
                
                
                
            } catch (Exception e) {
                System.out.println(e);
            }
       System.out.println( success );
        
    }
}
cs

jsp 파일의 form 으로부터 submit을 통해 GET 된 key와 captcha 값을 getParameter로 넘겨받아서 API에 접속하여 해당 값을 통해 검증이 이뤄진다. 해당 검증의 결과를 BufferedReader로 받아오게 되고, 다시 JSONObject를 생성해 결과를 입력해주고, success라는 Boolean값에 result 값을 입력해주면 된다.

위와 같이 완성하게 되고, text input에 입력한 값과 이미지의 key값을 통한 비교 결과가 출력된다.

profile
2년차 백엔드 개발자, crimy

0개의 댓글