jcaptchaの使い方
動いた!
Strutsのmoduleが含めれていますが、こいつが参考になりました。
jcaptcha自体はかなりDI指向な作りになっていますので、
DIコンテナで使うのは、かなり簡単みたいです。
登録したサービスはこのクラスのみ。
CAPTCHAクラス
以下は、ゆらゆら画像の出力処理。
WebWorkなんで、ServletActionContextをつかっていますが、
Strutsなんかでも基本は同じハズ。
CaptchaModuleConfigHelper.getId(request)で、セッションの中に
トークンのような物が作られるみたい。
HttpServletRequest request = ServletActionContext.getRequest(); HttpServletResponse response = ServletActionContext.getResponse(); String captchaID = CaptchaModuleConfigHelper.getId(request); byte[] captchaChallengeAsJpeg = null; ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream(); try { BufferedImage challenge = imageCaptchaService.getImageChallengeForID(captchaID, request.getLocale()); JPEGImageEncoder jpegEncoder = JPEGCodec .createJPEGEncoder(jpegOutputStream); jpegEncoder.encode(challenge); } catch (IllegalArgumentException e) { if (log.isWarnEnabled()) { log.warn("There was a try from " + request.getRemoteAddr() + " to render an URL without ID" + " or with a too long one"); response.sendError(HttpServletResponse.SC_NOT_FOUND); log.error("should never pass here!"); return ERROR; } } catch (CaptchaServiceException e) { log.warn("Error trying to generate a captcha and " + "render its challenge as JPEG", e); response.sendError(HttpServletResponse.SC_NOT_FOUND); return ERROR; } captchaChallengeAsJpeg = jpegOutputStream.toByteArray(); response.setHeader("Cache-Control", "no-store"); response.setHeader("Pragma", "no-cache"); response.setDateHeader("Expires", 0); response.setContentType("image/jpeg"); ServletOutputStream responseOutputStream = response .getOutputStream(); responseOutputStream.write(captchaChallengeAsJpeg); responseOutputStream.flush(); responseOutputStream.close(); return null;
入力された文字のチェックは以下のような感じ。
captchaResponseが入力された文字の場合、以下のようなコードになります。
1度でも認証に失敗するとトークンがなくなって、
2回目以降はエラーになります。
HttpServletRequest request = ServletActionContext.getRequest(); HttpServletResponse response = ServletActionContext.getResponse(); String captchaID = CaptchaModuleConfigHelper.getId(request); try { Boolean challengeObject = imageCaptchaService.validateResponseForID(captchaID, captchaResponse); boolean validateChaptchaResponceForID = challengeObject.booleanValue(); return validateChaptchaResponceForID; } catch (CaptchaServiceException e) { return false; }
ServletFilterは結局使ってなくて、注意点としてはEHCacheのJarが必要なとこ。