2023-10-20(금)
*참고) https://devchul.tistory.com/18
1. CASE
회원가입 시 자동 등록 방지 기능을 넣어야 했다. simplecaptcha라는 라이브러리를 사용하여 구현하기로 했다.
2. How to Use
0) 들어가기 전, CAPTCHA란?
웹사이트에서 사람이 접근하려고 하는 것인지 봇이 접근하는 것인지 판단하기 위하여 사용되는 테스트를 뜻한다.
1) 기본 세팅
① 공식 사이트(http://simplecaptcha.sourceforge.net/)에서 jar 파일을 다운로드 한다.
(여기서는 Java 6 버전을 다운로드했다!)
② 다운로드 한 jar 파일을 라이브러리에 Build Path를 한다.
2) Java 세팅
① /* Controller.java */
캡챠 컨트롤러를 호출하기 위한 Controller.java를 생성한다.
import nl.captcha.Captcha;
@RequestMapping(value="captchaImg.do")
public void captchaImg(HttpServletRequest req, HttpServletResponse res) throws Exception {
new CaptchaUtil().getImgCaptCha(req, res);
}
@RequestMapping(value = "captchaAudio.do")
public void captchaAudio(HttpServletRequest req, HttpServletResponse res) throws Exception {
Captcha captcha = (Captcha) req.getSession().getAttribute(Captcha.NAME);
String getAnswer = captcha.getAnswer();
new CaptchaUtil().getAudioCaptCha(req, res, getAnswer);
}
// 사용자가 입력한 보안 문자를 체크한다.
@RequestMapping( value = "captchachkAnswer.do", method = {RequestMethod.POST, RequestMethod.GET}, produces = "application/text; charset=utf8" )
@ResponseBody
public String captchachkAnswer(HttpServletRequest req, HttpServletResponse res) {
String result = "";
Captcha captcha = (Captcha) req.getSession().getAttribute(Captcha.NAME);
String answer = req.getParameter("answer");
if(answer!=null && !"".equals(answer)) {
if(captcha.isCorrect(answer)) {
req.getSession().removeAttribute(Captcha.NAME);
result = "200";
} else {
result = "300";
}
}
return result;
}
② /* CaptchaUtil.java */ 캡챠 컨트롤러
public class CaptchaUtil {
private static int width = 150; // 보안 문자 이미지 가로 크기
private static int height = 50; // 보안 문자 이미지 세로 크기
// CaptCha Image 생성
public void getImgCaptCha(HttpServletRequest req, HttpServletResponse res) {
// 폰트 및 컬러 설정
List < Font > fontList = new ArrayList < Font >();
fontList.add(new Font("", Font.HANGING_BASELINE, 40));
fontList.add(new Font("Courier", Font.ITALIC, 40));
fontList.add(new Font("", Font.PLAIN, 40));
List < Color > colorList = new ArrayList < Color >();
colorList.add(Color.BLACK);
Captcha captcha = new Captcha.Builder(width, height)
// .addText() 또는 아래와 같이 정의 : 6자리 숫자와 폰트 및 컬러 설정
.addText(new NumbersAnswerProducer(6), new DefaultWordRenderer(colorList, fontList))
.addNoise().addBorder()
.addBackground(new GradiatedBackgroundProducer())
.build();
// JSP에서 Captcha 객체에 접근할 수 있도록 session에 저장한다.
req.getSession().setAttribute(Captcha.NAME, captcha);
CaptchaServletUtil.writeImage(res, captcha.getImage());
}
// CaptCha Audio 생성
public void getAudioCaptCha(HttpServletRequest req, HttpServletResponse res, String answer) throws IOException {
HttpSession session = req.getSession();
Captcha captcha = (Captcha) session.getAttribute(Captcha.NAME);
String getAnswer = answer;
if(getAnswer == null || getAnswer.equals(""))
getAnswer = captcha.getAnswer();
AudioCaptcha audiocaptcha = new AudioCaptcha.Builder()
.addAnswer(new SetTextProducer(getAnswer))
//.addNoise() // 잡음
.build();
CaptchaServletUtil.writeAudio(res, audiocaptcha.getChallenge());
}
}
③ /* SetTextProducer.java */
오디오 캡챠가 전달받은 문자열을 사용할 수 있게 해준다.
public class SetTextProducer implements TextProducer {
private final String _getAnswer;
public SetTextProducer(String getAnswer) {
_getAnswer = getAnswer;
}
@Override
public String getText() {
return _getAnswer;
}
}
3) JSP 세팅
/* 캡챠 적용 시작 */
window.onload = function() {
getImage(); // 이미지 가져오기
document.querySelector('#check').addEventListener('click', function() {
var params = {
answer : $('#answer').val()
};
$.ajax({
type : "get",
url : "<c:url value='/01/01_captchachkAnswer.do'/>",
data : params,
dataType : "text",
success : function(returnData) {
if (returnData == 200) {
// 성공 시 코드
} else {
// 실패 시 코드
getImage();
}
}
});
});
}
// 매번 랜덤 값을 파라미터로 전달하는 이유
// : IE의 경우, 매번 다른 임의 값을 전달하지 않으면 '새로고침'을 클릭해도 정상적으로 호출이 되지 않기 때문에 이미지가 변경되지 않는 문제가 발생된다.
function audio() {
var rand = Math.random();
var uAgent = navigator.userAgent;
var soundUrl = 'captchaAudio.do?rand=' + rand;
if (uAgent.indexOf('Trident') > -1 || uAgent.indexOf('MISE') > -1) {
// IE 경우
audioPlayer(soundUrl);
} else if (!!document.createElement('audio').canPlayType) {
// Chrome 경우
try {
new Audio(soundUrl).play();
} catch (e) {
audioPlayer(soundUrl);
}
} else {
window.open(soundUrl, '', 'width=1,height=1');
}
}
function getImage() {
var rand = Math.random();
var url = 'captchaImg.do?rand=' + rand;
$('#captchaImg').attr('src', url);
}
function audioPlayer(objUrl) {
document.querySelector('#ccaudio').innerHTML = '<bgsoun src="' + objUrl + '">';
}
3. Reviewww
언제든지 쓰일 수 있는 기능이기에 간단한 기능이지만 정리해 봤다!