bravewood の日記

2007-11-18

[]symfonycaptchaを使う 10:41 symfonyでcaptchaを使うを含むブックマーク

captchaとはユーザー登録などで表示されるノイズが混じった文字列を表示しユーザーに読み取らせコンピュータなどが不正に複数アカウントを取得できなくする仕組みである.逆チューリングテストともいう.

f:id:bravewood:20071118103723p:image

symfonyではpluginとして3つのcaptcha実装が公開されている




  • sfReCaptchaPlugin



sfCryptographpPluginを使ってみる

3つのプラグインのうち

  • sfCaptchaPlugin はJpGraphが有償であるため却下
  • sfReCaptchaPluginはASP型なので却下

ということで単体で使えるsfCryptographpPluginを使うことにした.


使うまでに必要な流れ

旨くいけば1時間もかからないくらいで使えると思います.(もっと少ないかも)



インストール

コマンド一個で入ります.便利です.

使いたいプロジェクトのトップディレクトリで以下のコマンドを実行する

$ symfony plugin-install http://plugins.symfony-project.com/sfCryptographpPlugin

setting.ymlの設定

sfCryptographpPluginではplugin内にモジュールが存在する構成になっており,これを外部のtemplateなどからヘルパを通して呼び出す格好になります.

なので,プラグイン内のモジュールを使えるように設定しておく必要があります

app/yourapp/config/settings.yml

 all:
     .settings:
         enabled_modules:  [ default, cryptographp ]

ちなみにdefaultのモジュールは設定しなくても動きますが,error404などの際に呼び出されるモジュールがdefaultです.

とりあえず残しておいた方がいいと思います.

いらなくなれば後で外せます.



モジュールの設定

モジュールの設定では,実際にcaptchaの動作を実装するモジュール/アクションにおいてsfCryptographpを呼び出すコードを記述します.

また,sfCryptographpではユーザーの入力を検査する方法としてバリデータを使います.この設定もここで行います

action

ここではHogeというアクション内で呼び出す前提で説明します

app/yourapp/modules/yourmodule/actions/action.class.php

	public function executeHoge()
	{
		return sfView::SUCCESS;
	}
	
	public function handleErrorHoge()
	{
		return sfView::SUCCESS;
	}

template

sfCryptographpを呼び出すコードは3つです.すなわち

  • use_helper('Cryptographp');
  • echo cryptographp_picture();
  • echo cryptographp_reload();

app/yourapp/modules/yourmodule/template/hogeSuccess.php

 <?php use_helper('Cryptographp'); ?>
 
 <?php echo cryptographp_picture(); ?>
 <?php echo cryptographp_reload(); ?>
 
 <?php echo form_tag('@hoge') ?>
 <?php echo input_tag('crypto'); ?>
 <?php if ($sf_request->hasError('crypto')): ?>
	<?php echo $sf_request->getError('crypto') ?>
 <?php else: ?>
	OKです
 <?php endif ?>
 <?php echo submit_tag('submit') ?>
 </form>

validator

バリデータとしてsfCryptographpValidatorを呼び出せばOKです

app/yourapp/modules/yourmodule/validate/hoge.yml

 fields:
     crypto:
       required:
         msg:        'セキュリティコードの入力は必須です.'
         
       sfCryptographpValidator:
         code_error: '間違えました,もう一度入力くしてください'


app.ymlの設定

cryptographpの設定は全てこのファイルで行います

画像の幅であるとか,色とか文字の数などが設定できます.

設定の内容は後述しますので,とりあえずここでは基本的な設定をします.

ちなみに各設定値に対してはデフォルト値というのがplugin側で設定されていますのでこれらの値を設定しなくても動きますが,あとで変えられるように,最初から書いておきましょう.

app/yourapp/config/app.yml

 all:
     cryptographp:
         width: 150
         height: 60
         bg_r: 0
         bg_g: 0
         bg_b: 0
         bg_clear: false
         fonts: [ 'luggerbu.ttf' ]
         letters_range: 'ABCDEFGHKLMNPRTWXYZ234569'
         letters_easyread:   false
         letters_rangec: 'BCDFGHKLMNPRTVWXZ'
         letters_rangev: 'AEIOU'
         char_nb_min:    6
         char_nb_max:    6



キャッシュクリア

設定を変えたのでキャッシュはクリアしましょう

 $ symfony cc

実行結果

さて,ここまでで作ったモジュール/アクションにアクセスしてみましょう

以下のような感じにフォームが表示されればOKです.

f:id:bravewood:20071118102521p:image



フォームにcaptcha画像の文字を入力してsubmitを押すという簡単な操作です.

また,矢印の画像をクリックするとcaptcha画像が変わります.

フォームが送信されると,上記で設定したバリデータでバリデーションが行われ,captcha画像と同じ文字列が送信された場合はOKと表示され,文字が異なればエラーが表示されます.




設定を変える

設定の変更により文字サイズや色,使える文字など様々な値を変更することが可能です.

設定として何があるかということはpluginsディレクトリの以下のファイルに記述されていますので参照してください.(フランス語ですがgoogle翻訳などを活用して下さい)

plugins/sfCryptographpPlugin/lib/crypt/cryptographp.cfg.php




このファイルを見ると例えば以下のように記述されています.

 $cryptwidth  = sfConfig::get('app_cryptographp_width', 130);  // Largeur du cryptogramme (en pixels)

このうち設定値に該当するのは以下であり

app_cryptographp_width


それぞれ

  • app
    • が設定ファイル名
  • cryptographp
    • がネームスペース
  • width
    • が実際の設定名

となります

これを変更するには

app/yourapp/config/app.yml

 all:
     cryptographp:
         width: 150

などのように記述します.




さて,ここではよく使われるであろう設定値を抜き出して説明します.

ここでは,cryptographpのネームスペース以下の値について説明します.

  • 画像の横幅
    • width: 150
  • 画像の高さ
    • height: 60
  • 画像の背景を透過にするかどうかfalseにすれば画像の背景を有効に出来ます
    • bg_clear: false
  • 画像の背景色.各rgbで0から255までの値で設定します
    • bg_r: 0
    • bg_g: 0
    • bg_b: 0
  • 使用するフォント
    • fonts: [ 'luggerbu.ttf' ]
  • 文字列が母音と子音の読みやすい組み合わせで表示するかどうか.falseにすると単に指定した範囲内の文字がランダムで選ばれます
    • letters_easyread: false
  • 使用する文字の範囲.letters_easyreadがfalseの場合有効
    • letters_range: 'ABCDEFGHKLMNPRTWXYZ234569'
  • 使用する子音の範囲.letters_easyreadがtrueの場合有効
    • letters_rangec: 'BCDFGHKLMNPRTVWXZ'
  • 使用する母音の範囲
    • letters_rangev: 'AIUEO'
  • 表示される文字の長さの最小値
    • char_nb_min: 6
  • 表示される文字の最大値
    • char_nb_max: 6

面白い設定

設定値のうち重要なのが文字列の範囲だと思います.

sfCryptographpでは表示される文字を母音と子音の組み合わせで読みやすくするという方法がとれます.

有効(letters_easyread: true)にすると,例えば以下のような子音+母音の組み合わせて表示してくれるようになります

  • LAMULE
  • NOVOBI


また無効(letters_easyread: false)にすると,以下のように適当な文字が表示されます.

  • NCKYLW
  • ANCMBX

日本人にとっては子音+母音の組み合わせが読み取りやすく一時記憶にも残りやすいので有効にする方がいいように思います.


使えるフォント

さて,captcha実装はそこら中で見かけますが,中にはフォントが見にくいなあと思うものがあり,何度も読み間違えることもしばしばです.

もちろんめちゃくちゃ読みやすい文字を表示してしまうとコンピュータにも読み取られてしまい,不正な利用をはじくことになりませんが,ユーザービリティを考えると読みやすいフォントを使うのはいいことだと思います.

sfCryptographpPluginではインストールによっていくつかのフォントがpluginと一緒にインストールされます.

インストールされるのは以下の場所です

plugins/sfCryptographpPlugin/lib/crypt/fonts/


7つインストールされます

  • Alanden_.ttf
  • bsurp___.ttf
  • ELECHA__.TTF
  • luggerbu.ttf
  • RASCAL__.TTF
  • SCRAWL.TTF
  • WAVY.TTF

このうち読み取りやすいなあと思ったのは2つです

  • Alanden_.ttf

f:id:bravewood:20071118110259p:image

  • luggerbu.ttf

f:id:bravewood:20071118110443p:image



逆にそれ以外はちょっと読みづらいなあと思いました.

例えば

  • WAVY.TTF

左から4文字目は小文字のeに見えますがcです.

f:id:bravewood:20071118110710p:image


複数フォントを使う

上記では単体フォントを使いました.

フォントを固定してしまうと以下のエントリのように簡単に破られてしまいます.

もちろん破られないように難しいフォントを使うのもいいですが,フォントを固定せずに複数組み合わせるという方法も有効ではないでしょうか.

http://blogs.wankuma.com/nagise/archive/2007/10/26/104428.aspx

http://b.hatena.ne.jp/entry/6303503



sfCryptographpPluginではfontの指定に配列を渡してやれば,複数のフォントが同じ画像で使われます.

以下の画像ではRASCAL__.TTF と Alanden_.ttf を組み合わせています

f:id:bravewood:20071118111743p:image

設定は以下のように[]記述の配列で指定します.

all:
    cryptographp:        
        fonts: [ 'RASCAL__.TTF', 'Alanden_.ttf'   ]

まとめと特徴

  • 文字がそれぞれ別々の色である
  • フォントプラグインに含まれる
  • 子音と母音の読みやすい組み合わせで表示できる
  • 設定はapp.ymlで行う

とにかく簡単にインストールでき,簡単に使うことが出来る.

設定によってカスタマイズすることも出来る.

ぜひ使ってみてはどうだろうか.