CAPTCHA に挑戦してみた

 故あって CAPTCHA に挑戦してみました。CAPTCHA とは何かということははてなキーワードに任せるとして、私は JCAPTCHA を使って実装してみました。しかし Google 等で検索してみて見つかるサンプルで生成される画像は人間すら読むのが困難なものばかり。それどころか Windows でなければ動かなかったり、とても実用に耐えません。

 そこで JCAPTHCA の少ない情報をなんとかほじくり返して見ると、どうやら DI と相性がよいとのこと。そして、カスタマイズするのに Spring がどうたらこうたらというくだりを発見したのですが、無駄に Spring に対抗心を燃やしている Seasar ファンの私としては、Seasar でやったるわい! と奮起したわけであります。

 ということで、題して S2Captcha ができました(以降のアーカイブにはソースも含まれていますので参考にしてください)。

s2captcha-0.2.1.zip

使い方

 まず JCAPTCHA の Web サイト( http://jcaptcha.sourceforge.net/ )から、JCAPTCHA をダウンロードしてきてライブラリ( jcaptcha-all-1.0-RC3.jar )を WEB-INF/lib に入れておきます。

 次に s2captcha-0.2.1.jar を WEB-INF/lib に入れ、同梱の s2captcha.dicon を app.dicon があるディレクトリにおいて以下のように app.dicon に書き加えてインクルードします。

    <include path="s2captcha.dicon" />

 最後に以下のように web.xml に書き加えてサーブレットを登録します。

    <servlet>
      <servlet-name>captcha</servlet-name>
      <servlet-class>net.of_my.s2captcha.servlet.ImageCaptchaServlet</servlet-class>
      <load-on-start-up>3</load-on-start-up>
    </servlet>
    <servlet-mapping>
      <servlet-name>captcha</servlet-name>
      <url-pattern>/captcha.jpg</url-pattern>
    </servlet-mapping>

 これで準備 OK です。これで [あなたのサーブレットルート]/captcha.jpg にアクセスしてみてください。↓ こんな画像が表示されれば成功です。

CAPTCHA チェックをしてみよう

 表示するだけでは何の役にも立ちませんね。ではどうやってチェックすればいいのでしょうか? Pure Servlet(?)でもチェックすることはもちろんできるのですが、Seasar を使っているのでしたら、S2JSF なり Teeda Extension なりを使っているでしょう。そこで、JSF 用バリデータを用意しました。

s2captcha-faces-validator-0.2.1.zip

 さらに TeedaTiger アノテーションに対応するものも用意しました。

s2captcha-teeda-tiger-0.2.1.zip

 これらを WEB-INF/lib に入れてください。

 では、Teeda Extension を例に説明します。まず app.dicon に次のように書き加えてください。

    <include path="s2captchaFaces.dicon" />

次にテンプレートを作成します。captcha.html という名前で以下のようにします。

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>CAPTHCA Test</title>
  </head>
  <body>
    <form id="form">
      <p>
        <span id="allMessages"></span>
      </p>
      <p>
        <img src="../../captcha.jpg" id="captchaImg" /><br />
        <input type="text" id="captcha" title="きゃぷちゃ" />
        <input type="submit" value="check" id="doFinish" />
      </p>
    </form>
  </body>
</html>

 最後に CaptchaPage クラスは以下のようにします。

package example.web.test;

import net.of_my.s2captcha.teeda.annotation.Captcha;

import org.seasar.teeda.extension.annotation.validator.Required;

public class TestPage {

    private String captcha;

    public String getCaptcha() {
        return captcha;
    }

    @Required
    @Captcha
    public void setCaptcha(String captcha) {
	this.captcha = captcha;
    }

    public String initialize() {
        return null;
    }

    public String prerender() {
        return null;
    }

    public String doFinish() {
        return "ok";
    }
}

これで OK。もしエラーメッセージが気に食わなければ、Captcha アノテーションの messageId にメッセージ ID を指定してください。