본문 바로가기

Spring boot

Spring Boot 보안문자 Captcha 적용하기 (자동가입 방지)

1. captcha 적용을 위한 library 다운로드 (아래 링크)

http://simplecaptcha.sourceforge.net/

 

 

SimpleCaptcha - A CAPTCHA framework for Java

SimpleCaptcha is a Java library for generating CAPTCHA challenge/answer pairs. SimpleCaptcha is intended to be easy to implement and use sensible defaults, while providing easily-accesssible hooks for customization. Example implementations are provided in

simplecaptcha.sourceforge.net

오른쪽 다운로드의 java 6 가장 최신 버전으로 다운받아서 진행

(참고로 제 개발환경은 11)

 

2. 받은 library를 추가 (intellij 기준)

project structure에 libraies에 받은 jar 파일을 추가합니다.

 

3. Captcha Util 생성

CaptchaUtil class 파일을 생성합니다.

package han.co.platform.shop.common.util;

import han.co.platform.shop.common.model.Response;
import nl.captcha.Captcha;
import nl.captcha.audio.AudioCaptcha;
import nl.captcha.backgrounds.GradiatedBackgroundProducer;
import nl.captcha.servlet.CaptchaServletUtil;
import nl.captcha.text.producer.NumbersAnswerProducer;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;

public class CaptchaUtil {

    public void captcaImg(HttpServletRequest request, HttpServletResponse response) {
        Captcha captcha = new Captcha.Builder(200, 60)
                .addText(new NumbersAnswerProducer(6))
                .addNoise().addNoise().addNoise()
                .addBackground(new GradiatedBackgroundProducer())
                .addBorder()
                .build();

//        response.setHeader("Cache-Control", "no-cache");
//        response.setDateHeader("Expires", 0);
//        response.setHeader("Pragma", "no-cache");
//        response.setDateHeader("Max-Age", 0);

        request.getSession().setAttribute(Captcha.NAME, captcha);
        CaptchaServletUtil.writeImage(response, captcha.getImage());

    }

    public void captchaAudio(HttpServletRequest request, HttpServletResponse response, String answer) {
        Captcha captcha = (Captcha) request.getSession().getAttribute(Captcha.NAME);
        String getAnswer = answer;

        if(getAnswer == null || getAnswer.equals("")) getAnswer = captcha.getAnswer();

        AudioCaptcha ac = new AudioCaptcha.Builder()
                .addAnswer(new SetTextProducer(getAnswer))
                .addVoice()
                .addNoise()
                .build();

//        response.setHeader("Cache-Control", "no-cache");
//        response.setDateHeader("Expires", 0);
//        response.setHeader("Pragma", "no-cache");
//        response.setDateHeader("Max-Age", 0);

        CaptchaServletUtil.writeAudio(response, ac.getChallenge());

//        request.getSession().setAttribute("captcha", ac.getAnswer());
    }

    public Response chkAnswerProcess(HttpServletRequest request, HashMap<String, String> p) {
        Response response = new Response();

        response.setDataObj("1");

        return response;
    }

}

 

그리고 작성한 Captcha Util을 호출해줄 controller를 작성

 

// 보안문자 이미지 가져오기
@RequestMapping(value="/getCaptchaImg")
public void captchaImg(HttpServletRequest request, HttpServletResponse response) throws Exception {
new CaptchaUtil().captcaImg(request, response);
}

// 보안문자 오디오
@RequestMapping(value="/getCaptchaAudio")
public void captchaAudio(HttpServletRequest request, HttpServletResponse response) throws Exception {
Captcha captcha = (Captcha) request.getSession().getAttribute(Captcha.NAME);
String getAnswer = captcha.getAnswer();
new CaptchaUtil().captchaAudio(request, response, getAnswer);

 

보여줄 화면 html 작성

<div class="form-group">
<label style="display:block">자동 로그인 방지</label>
  <div class="captcha">
    <div class="captcha_child">
    	<img id="captchaImg" title="캡차 이미지" src="/common/getCaptchaImg" alt="캡쳐 이미지">
    	<div id="captchaAudio" style="display: none;"></div>
    </div>
    <div class="captcha_child_two">
      <a class="refreshBtn" id="refreshImg">
      	<i class="fa fa-refresh" aria-hidden="true"></i>새로고침
      </a>
      <a class="refreshBtn" id="audio">
      	<i class="fa fa-volume-up" aria-hidden="true"></i>음성듣기
      </a>
    </div>
    <div>
      <input type="text" id="answer" value="" />
      <button id="check">확인</button>
    </div>
  </div>
</div>

 

마지막으로 script 작성

this.getCaptchaImg = function() {

            var rand = Math.random();
            var url = '/common/getCaptchaImg?rand='+rand;

            $("#captchaImg").attr("src", url);

        },
        this.getCaptchaAudio = function() {
            var rand = Math.random();

            var ajaxUtil = new AjaxUtil();

            var dataObj = {};
            dataObj.rand = rand;

            var setObj = {
                url: '/common/getCaptchaAudio',
                callback: this.captchaAudioAjaxCB,
                data: dataObj
            };

            ajaxUtil.ajaxCall(setObj);

        },
        this.captchaAudioAjaxCB = function(data, textStatus) {
            var rand = Math.random();
            var soundUrl = '/common/getCaptchaAudio?rand='+rand;
            var agent = navigator.userAgent;

            if(agent.indexOf('Trident') > -1 || agent.indexOf('MSIE') > -1) {
                winPlayer(soundUrl);
            } else if(!!document.createElement('audio').canPlayType) {
                try {
                    new Audio(soundUrl).play();
                } catch (e) {
                    tpTestSecurityObj.winPlayer(soundUrl);
                }
            } else {
                window.open(soundUrl, '', 'width=1, height=1');
            }
        },
        this.winPlayer = function(objUrl) {
            $("#captchaAudio").html("<bgsoun src="+objUrl+'">');
        },
        this.checkCaptcha = function() {

            var ajaxUtil = new AjaxUtil();

            var dataObj = {};
            var answer = $("#answer").val();

            if(answer != "") {
                dataObj.answer = answer;

                var setObj = {
                    url: '/common/chkAnswerAjax',
                    callback: this.chkCaptchaAjaxCB,
                    data: dataObj
                };

                ajaxUtil.ajaxCall(setObj);
            } else {
                toastr.error("보안 문자를 입력해주세요.");
                $("#answer").focus();
            }

        },
        this.chkCaptchaAjaxCB = function (data, textStatus) {
            console.log("chkCaptchaAjaxCB" + data);
        }

'Spring boot' 카테고리의 다른 글

intellij에서 xml파일 build 안될 때 설정  (0) 2021.06.24
Spring boot jar파일 배포  (0) 2021.06.24
Spring Boot 시작하기  (0) 2021.06.23