メールフォームCLIP-MAILにCaptcha認証(アンチスパム画像認証)をカスタマイズする。
(PHP + Ajax)
アンチスパム画像の作成には、PHP JpGraphライブラリーを使用。

1. 使用ファイル2. 使い方3. サンプル

KENT-WEBのフォームメールには、画像認証機能(スパム対策用)が付いたフォームメールCaptcha Mailがあります。
だだし、そのアンチスパム画像が単純のため好まない場合は、PHP JpGraphライブラリーを使用して作成したアンチスパム画像をKENT WEBのClip Mailにカスタマイズすることを 薦めます。

●アンチスパム画像例 ― ;
 【例1】 KENT WEB Captcha Mail のアンチスパム画像
 【例2】 PHP JpGraph のアンチスパム画像

 1.使用ファイル

     使用ファイル

  1. xxxxx.html : TOPページ clipmail対応入力フォームHTML(自作)。
  2. KENT WEB CLIP-MAIL (CGI): KENT WEB サイト から「CLIP-MAIL」をダウンロードします。、
    また、CLIP-MAILのメインCGIの clipmail.cgi のカスタマイズ版 clipmail2.cgi を本サイトからダウンロードします。
  3. jpgraphアンチスパム画像生成ライブラリー(jpgraph_antispam.php): Asial サイト から「JpGraphコミュニティ版」をダウンロードします。
  4. captcha処理関数(PHP/javascript) : 本サイトからダウンロードします。
  5. jQuery : jQuery CDNサイトのURLをインクルードしてファイルを直接使用します。

     サーバーディレクトリ構成成例  ( :フォルダ   :ファイル )

 antispam (サーバーパス例:/public_html/webutil/antispam)
    +  captcha ← captcha処理関数
    |     +  captcha-auth.js ← 画像認証処理関数の起動関数およびアンチスパム画像変更関数
    |     +  captcha-authimage.php ← 画像認証処理関数
    |     +  captcha-createimage.php ← アンチスパム画像生成処理関数
    +  clipmail ← CLIP-MAIL
    |     +  data
    |     +  lib
    |     +  upl
    |     +  tmpl
    |     +  admin.cgi      [705] ... 管理画面
    |     +  check.cgi      [705] ... 動作チェックプログラム
    |     +  clipmail.cgi   [705] ... Clipmail本体
    |     +  clipmail2.cgi  [705] ... Clipmail本体のカスタマイズ版
    |     +  index.html ← カスタマイズ対象HTML
    |     +  init.cgi       [604] ... 設定ファイル
    |     +  style.css
    +  jpgraph ← JpGraph
    |     +  jpgraph_antispam.php ← アンチスパム画像生成ライブラリー
    +  clipmail-captcha.html  ← このページ(自作) 
    +  index.html  ← カスタマイズ済みHTML(clipmailフォルダのindex.htmlよりコピーして使用) 

 2.TOP 入力フォームHTMLの書き方

使い方はつぎのとおりです。サンプルは、clipmailフォルダのindex.htmlをカスタマイズします。

  1. ファイルのダウンロードおよびアップロード (事前準備 - サーバー)

    上記使用ファイルについて、3サイトからダウンロードし、上記「サーバーディレクトリ構成成例」に従い、必要ファイルをサーバへアップロードします。
  2. jQueryおよびcaptcha-auth.js のインクルード (HTML)

    index.htmlにつぎのコードを追加します。
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
    <script src="./captcha/captcha-auth.js"></script>
    captcha-auth.jsは、画像認証関数(auth関数)および認証画像変更関数(onclick関数)の2つの機能を有します。

  3. 入力フォームのカスタマイズ方法(HTML)

    index.htmlのフォームの中に 項番2から4のコードを追加します。
    また、項番1 Formタグおよび項番5 submitボタンのコードを変更修正します。

    表 index.html フォームカスタマイズ内容
    項番項目名タグ備考
    formタグ<form name="Qform" action="./clipmail/clipmail2.cgi" method="post" enctype="multipart/form-data">name属性追加およびaction属性のURL修正
    (赤字)
    画像認証の入力文字<input type="text" name="InputWord" value="">追加
    画像認証の画像文字<input type="hidden" name="ImageWord" value="">追加。 画像認証処理関数が設定。
    画像認証の画像生成<img id="CaptchaImage" src="./captcha/captcha-createimage.php?p=c&len=6">追加
    画像認証の画像変更<input type=button id="ImageChange" value="認証画像変更">追加。 アンチスパム画像変更関数。
    サブミットボタン
    (画像認証処理+サブミット)
    <input type="button" value="送 信" onclick="Auth(this.form,0,1)">ソースの57行目の
    <input type="submit" value="送信する">
    サブミットボタンを修正(赤字)

  4. 4つのcaptcha処理関数 の使い方および機能説明(HTML)

  5. CLIP-MAIL本体 clipmail.cgi のカスタマイズ方法(CGI)

    フォーム送信後のエラーリストや確認画面において、「画像認証の入力文字」項目および「画像認証の画像文字」項目(上表項番2、3)の表示をつぎのようにする場合、clipmail.cgi のカスタマイズが必要です。

     【画像1】
    左画像はカスタマイズなしの場合いの走行例です。
    フォームのname値はinit.cgiで置き換えをしています。

    'InputWord' => '画像認証-入力文字',
    'ImageWord' => '画像認証-画像文字'。

    (1)フォーム送信後のエラーリストや確認画面において、アンチスパム画像の文字を表示することは好ましくないので、
    追加の「画像認証の画像文字」項目(上表項番3)を表示したくない場合、つぎのコードを2箇所に追加します。 (例1)
             next if ($key eq "ImageWord" && $authck eq "nocheck");  # clipmail.cgi 210行目の次に追加
    
             next if ($key eq "ImageWord" && $authck eq "nocheck");  # clipmail.cgi 652行目の次に追加

     【画像2】
    左画像は、例1の走行例です。


    (2)逆に、フォーム送信後のエラーリストや確認画面において、画像認証蹴結果の正常・異常について、追加の「画像認証の入力文字」項目および「画像認証の画像文字」項目(上表項番2、3) を表示したい場合、つぎのコードを追加します。(例2)
    # Captcha画像認証チェック clipmail.cgi 70行目の次に追加 (コメント含む 15 ステップ追加)
    my $imgword = $$in{ImageWord};
    my @imgstr = split(/,/, $imgword);
    my $imgword = $imgstr[0];
    my $authck = $imgstr[1];
    $$in{ImageWord} = $imgword;
    if ($authck eq "check"){
      if( $$in{InputWord} eq $$in{ImageWord} ){
         $$in{ImageWord} = "OK! 入力した文字と一致しました。";
        }
      else{
         $$in{ImageWord} = "NG! 入力した文字と一致しません。";
         $check++;
       } 
    }
    

     【画像3】
    左画像は、例2のカスタマイズした走行例です。


 3. サンプル

サンプルは、Clipmail+Captcha認証サンプルデモおよびindex.htmlのフォーム部分のカスタマイズしたHTMLコードを表示しています。

<!-- 赤字部分は追加、青字部分は変更 -->
<form name="Qform" action="./clipmail/clipmail2.cgi" method="post" enctype="multipart/form-data">
<input type="hidden" name="need" value="name email 問合せ種別">
<input type="hidden" name="sort" value="name email 問合せ種別 メッセージ">
<input type="hidden" name="match" value="email email2">
<div id="form-tbl">
<table summary="問合せフォーム" id="form">
<tr>
	<th valign=top>お名前</th>
	<td><input type="text" name="name" size="35"></td>
</tr><tr>
	<th valign=top>メールアドレス</th>
	<td>
		<input type="text" name="email" size="35"><br>
		<input type="text" name="email2" size="35"> (再度入力)
	</td>
</tr><tr>
	<th valign=top>問合せ種別</th>
	<td>
		<input type="radio" name="問合せ種別" value="ご質問">ご質問<br>
		<input type="radio" name="問合せ種別" value="ご相談">ご相談<br>
		<input type="radio" name="問合せ種別" value="ご感想">ご感想<br>
		<input type="radio" name="問合せ種別" value="ご依頼">ご依頼<br>
		<input type="radio" name="問合せ種別" value="その他">その他
	</td>
</tr><tr>
	<th valign=top>問合せ内容</th>
	<td><textarea name="メッセージ" rows="7" cols="55"></textarea></td>
</tr><tr>
	<th valign=top>添付ファイル</th>
	<td>
		<input type="file" name="clip-1" size="40"><br>
		<input type="file" name="clip-2" size="40"><br>
		<input type="file" name="clip-3" size="40">
	</td>
</tr>
<tr>
	<th valign=top>画像認証</th>
	<td>
          <table><tr>
           <td valign=top><input type="text" name="InputWord" value=""><br></td>
           <td  valign=top>画像の文字を入力してください。<br>英字は小文字で入力します。<br>(例) T → t<br>
            </td>
           <td><img id="CaptchaImage" src="./captcha/captcha-createimage.php?p=c&len=6&str=jpgraph4&auth=yes" /><br>
             <input type=button id="ImageChange" value="認証画像変更"> <!--  ↑ Pパラメータ a:文字列自動 s:文字列入力 c:文字列内部定義  -->
	   </td>
          </tr></table>
	</td>
</tr><tr>
	<th></th>
	<td>
<p class="btn" style="">
	<input type="button" value="送 信" onclick="Auth(this.form,1,0)"> 
	<input type="reset" value="リセット">  <font color=red><b>※</b></font> 
</p>
	</td>
</tr>
</table>
              <input type="hidden" value="" name="ImageWord"> <!-- クッキーの画像の文字を返す-->
</form>

// captcha-authimage.php 認証PHPの起動 2018.11.21 ////////////////////////////////
//グローバル変数
var sf;
var ck;
var imgword;
function Auth(obj,s,c){
  sf = "";
  if( s == 0){ sf = "ok"; }       // 0のとき、画像認証結果のOKの場合のみサブミットする
  else{ sf = "any"; }             // 0以外のとき、画像認証結果のOK,NGに関わらずサブミットする 
  ck = "";
  if( c == 0){ ck = "nocheck"; }  // 0のとき、送信(サブミット)後のエラーリストや確認画面に画像認証結果を表示しない
  else{ ck = "check"; }           // 0以外のとき、送信(サブミット)後のエラーリストや確認画面に画像認証結果を表示する 
  var inword = obj.InputWord.value;
  imgword = "";
  
          var phpurl = "http://urbanqee.com/webutil/antispam/captcha/captcha-authimage.php";     // 要修正 *******
               console.log(phpurl);

          $.ajax({
               type : "POST",
               url : phpurl,
               data : {
                    "inputword" : inword
               }
          }).done(function(data){
             data_arr = JSON.parse(data);
             //alert(data_arr[0]+"/"+data_arr[1]);
             imgword = data_arr[1];
             if(data_arr[0] == "ok"){ authOK(obj,imgword); }
             else if(data_arr[0] == "error1"){ authNG1(obj,imgword); } 
             else { authNG2(obj,imgword); } 
          }).fail(function(data) {
             data_arr = JSON.parse(data);
             return false;
          });
 return true;
}

function authNG1(obj,imgword){
       alert( "認証 エラー!\n入力した文字が正しくありません!");
       if(sf == "any"){
             obj.ImageWord.value = imgword + "," + ck; //画像文字設定   
             obj.submit();  //送信 
        }
}

function authNG2(obj,imgword){
       alert( "認証 エラー!\n入力できるのは半角の数字・英小文字だけです。\nただし、数字0(ゼロ)、英字 o(オー)は除きます。");
       if(sf == "any"){
             obj.ImageWord.value = imgword + "," + ck; //画像文字設定   
             obj.submit();  //送信 
        }
}

function authOK(obj,imgword){
    obj.ImageWord.value = imgword + "," + ck; //画像文字設定  
    //alert(obj.ImageWord.value); 
    obj.submit(); //送信  
}

//認証画像変更 onloadおよびボタンクリックで変更 /////////////////////////////////////////////
$(window).on('load',function(){
  $('input#ImageChange').on('click', function(){ 
    //$('#captchaImage').children('img').attr('src', './captcha/captcha-createimage.php?p=c&len=6&str=abc234&auth=yes');
    var src = './captcha/captcha-createimage.php?p=c&len=6&str=abc234&auth=yes';
    $('#CaptchaImage').attr('src', src + '&' + new Date().getTime());
    return true;
    //$("#captchaImage").attr("src", "/myimg.jpg?timestamp=" + new Date().getTime());
  });
});
 

<?php
// 認証処理 2018.11.21
$res = "";
if (isset($_REQUEST["inputword"])) {
        $imgcode = $_COOKIE['AntiSpamChars'];   //画像文字コード 
        if(! preg_match( '/^[1-9a-np-z]+$/', $_REQUEST['inputword'])) {    //NG
                $res = array("error2", $imgcode);
		//echo json_encode($res);
	} else if ($_REQUEST['inputword'] == $_COOKIE['AntiSpamChars']) {  //OK
                $res = array("ok", $imgcode);
		//echo json_encode($res);
	} else {                                                            //NG
                $res = array("error1", $imgcode);
		//echo json_encode($res);          
	}
echo json_encode($res);
}

?>
 

<?php 
// Antispam画像生成モジュール 2018.11.21
require_once "../jpgraph/jpgraph_antispam.php";

// Antispam オブジェクト
$spam = new AntiSpam();

$randamstr = "123456789abcdefghijkl123456789mnopqrstuvwxyz123456789"; //ランダム抽出文字列 数字0と英字oは紛らわしいので除く

//入力パラメータ
$p = $_REQUEST['p']; //a:文字列自動 s:文字列入力 c:文字列内部定義
$len = $_REQUEST['len'];
$auth = "yes";
if (isset($_REQUEST["auth"])){
    $auth = $_REQUEST['auth'];
}
$out = "f";
if (isset($_REQUEST["out"])){
    $out =  $_REQUEST['out'];   //生成画像出力先 w:画面表示(Window)  f:ファイル出力(File)
}
$str = "";

//処理開始
if ($p == "a"){
      $str = $spam->Rand($len);
   }
elseif($p == "s"){
  $str = $_REQUEST['str']; //p=sの場合文字列
  $spam -> Set($str); 
}
else{   // p=c $randamstrから指定桁数の文字列をランダムに取り出す

  $str = substr(str_shuffle($randamstr), 0, $len);
  $spam -> Set($str); 
}

// クッキー設定
if($auth == "yes"){
 setcookie("AntiSpamChars", $str, time() + 300);	//300秒間有効なCookie
 //$v = $_COOKIE['AntiSpamChars'];
 //print($v);   //$_COOKIE['AntiSpamChars'];  //画像文字コード
}

// Stroke random cahllenge
if ($out == "w"){  //画面表示
   if( $spam->Stroke() === false ) {
       die('Illegal or no data to plot');
    }
}
else{    //ファイル出力
   if( $spam->Stroke("./tmp/antispam-$str.jpg") === false ) {
       die('Illegal or no data to plot');
    }
}

?>
 
 サンプルデモを新しいウインドウで見る

1. 使用ファイル2. 使い方3. サンプル




 最終更新日:2018.11.21(Debut)
メール mailto:  掲示板