誤字っぽいけど誤字じゃない、とても昔からあるJAVA用のCAPTCHA認証ライブラリが「Kaptcha」です。
現代ではあまり利用されることはないかも知れませんが、限られた環境下ではもしかしたら採用される可能性があるかも、と思ったので備忘録としてここに残しておくことにしました。
「Kaptcha」とは
「Kaptcha」は、Javaプログラミング言語用のCAPTCHA(Completely Automated Public Turing test to tell Computers and Humans Apart)生成ライブラリです。ユーザーが人間であることを証明するためにテキストを読み取ったり、画像内の特定のパターンを識別したりすることを要求することで、一般的なユーザID+パスワードの組み合わせに追加する形で用いられます。
Kaptchaライブラリは、これらのCAPTCHAを生成するためのJavaライブラリであり、簡単に使用することができます。また、カスタマイズも比較的容易に実施できます。ただまあ、UI的にはちょっと古さを感じるかも。
Kaptchaの主な特徴はざっくり以下のとおりです。
- カスタマイズ可能: Kaptchaは、生成されるCAPTCHAの外観や動作をカスタマイズするための多くの設定オプションを提供します。これによって、表示テキストのバリエーション、文字数などプロジェクトに合わせた設定にすることができる
- 組み込みやすい: Kaptchaは、Javaのウェブアプリケーションフレームワーク(Springなど)に組み込みやすい
- 画像生成:Kaptchaは、画像としてCAPTCHAを生成します。この画像は、ユーザーに表示され、テキストを読み取ったりパターンを識別するための入力が求められます。
- ランダムなテキスト: Kaptchaは、ランダムなテキストを生成し、それをCAPTCHAとして表示します。
- オープンソース: Kaptchaはオープンソースプロジェクトであり、無料で使用できます。
詳しいことは以下の公式ドキュメントに記載があります。(英語)
https://code.google.com/archive/p/kaptcha/
最終更新が2010年と、やっぱり歴史を感じるライブラリですね。
実装方法
Kaptchaライブラリ(jar)をダウンロードする
ライブラリを以下よりダウンロードします。
https://code.google.com/archive/p/kaptcha/downloads
開発環境にライブラリを追加、参照できるようにする
各々の環境でライブラリを利用可能な状態とします。
「web.xml」にコードを追加
「web.xml」にコードを追加します。
<servlet>
<servlet-name>Kaptcha</servlet-name>
<servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Kaptcha</servlet-name>
<url-pattern>/kaptcha.jpg</url-pattern>
</servlet-mapping>
url-patternに記載した文字列が生成される画像名になります。kaptchaのままだとアレなので、適当に差し替えて置きましょう。これでコンテキストはいかに上記の名前で画像が生成されるようになります。
また、以下のように記載を追加することで、設定変更ができます。また、記載がないパラメータはライブラリの初期値がも通られます。
<init-param>
<param-name>kaptcha.textProducer.char.string</param-name>
<param-value>abcde2345678gfynmnpwx</param-value>
</init-param>
この例では、表示されるテキストのバリエーションを定義しています。
パラメータの一覧は以下となります。
https://code.google.com/archive/p/kaptcha/wikis/ConfigParameters.wiki
まwiki公式の参考は以下です。ほかのページについてもここから辿っていくと良いでしょう。
https://code.google.com/archive/p/kaptcha/wikis/HowToUse.wiki
Webサーバーでの処理にコードを追加
画像を生成しただけでは意味をなさないので、ログイン処理などのサーバー処理にこんな感じで処理を追記します。
// SESSIONから画像に表示した文字列を取得
String kaptchaTxt = (String)request.getSession().getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
// ユーザが入力したキャプチャ文字列を取得
String inputTxt = request.getParameter("kaptcha");
// 入力値がない場合、入力値と画像表示値が一致しない場合はエラー
if (inputTxt == null || !inputTxt.equals(kaptchaTxt)) {
// エラーハンドリング
}
これで簡易的なキャプチャ認証処理が実装できます。
また、キャプチャ認証によくある、画像を更新する機能だったりはjavaScriptで出来たりするので、必要に合わせて実装すると良いでしょう。正直「なくてOK!」とはならない気がしてますが。いずれにせよ細かいチューニングは必要かなと思います。
最後に
2段階認証を実装するのが現在の流れではありますよね。コストの兼ね合いくらいでしかキャプチャ認証の採用はないのかも知れない。。