WordPressでサイトログイン時のセキュリティアップを目的としてよく使われているGoogle reCAPTCHA。セキュリティアップ系のプラグインなどを使うと同梱されていて利用している方も多いでしょう。
Google reCAPTCHAは膨大なデータの中から人間かどうかを判別する仕組みになっていて、より確実にセキュリティアップができるものの、外部と接続する機構上キーの取得が必要だったり、認証時にエラーが出たりすることがあります。
参考:GoogleのreCAPTCHAはどうやって人間とボットを見分けているのか?
今回はそこまでのセキュリティは必要ないという方、外部とのやり取りはせずにセキュリティアップを図りたいという方のために、ログイン画面に計算式を表示させ、正確な回答をしたかを認証させるようにするコードを紹介します。
実装できる機能
本ページのコードを追加することで以下のような機能を実装できます。
- ログイン画面に足し算の計算問題をランダムに出題する
- ユーザー名、パスワードと共に計算問題に正答した場合のみログインできる
- 計算問題の解答に誤りがある場合や空欄のままログインしようとするとログインを拒否し、サイト管理者メールアドレスへ警告メールを送信する
以下がコード追加後のログイン画面イメージです。

本ページ掲載のコードを使用するときは
本ページで掲載しているコードは、以下に了承した上で使用ください
- コードは商用・非商用問わず自由に使っていただいて構いませんが、コード追加による不具合やトラブルが発生しても当方では一切責任を負いません
- コードは有効化しているテーマのfunctions.php、style.cssなどへ追加することで機能します。それらのファイルへの変更を行うことに不安のある方は使用しないでください
- コードは本ページの公開日時点で私の環境において動作したものです。WordPressバージョン他環境の違いによって動作しないことがあります
- コードは、セキュリティ、コードの正確さなどにおいて完全なものではありません。中には紹介するコードを簡略化するために省略している部分があるものもありますので、ご自身でコードを十分に検証し、必要な部分の編集を行った上で使用するようにしてください
- 掲載しているのは参考コードです。自身の環境に合わせるための編集はご自身で対応いただく必要があります(コメント欄等から質問いただいても基本回答は致しません)
- 掲載しているコードの転載を禁じます(SNSで紹介いただいたり、本ページへのリンクを張っていただくことは大歓迎です)
ログイン画面に計算問題認証機能を追加するコード
以下のコードを有効化しているテーマのfunctions.phpへ追加すると機能します。
/***** ログインフォームに足し算を追加 *****/
/* ランダムな足し算の問題を生成 */
function pwcn_generate_math_problem() {
$num1 = rand(1, 10);
$num2 = rand(1, 10);
$answer = $num1 + $num2;
$token = base64_encode($answer);
return [
'problem' => "$num1 + $num2 = ?",
'token' => $token,
];
}
/* ログインフォームに計算問題を追加 */
function pwcn_add_math_problem_to_login() {
$math_data = pwcn_generate_math_problem();
$nonce = wp_create_nonce('pwcn_login_math_nonce'); // Nonceの生成
$output = '';
$output .= '<p>';
$output .= '<label for="pwcn_math_answer">計算問題: ' . $math_data['problem'] . '</label><br />';
$output .= '<input type="hidden" name="pwcn_math_token" value="' . $math_data['token'] . '" />';
$output .= '<input type="hidden" name="pwcn_login_math_nonce" value="' . $nonce . '" />';
$output .= '<input type="text" name="pwcn_math_answer" id="pwcn_math_answer" required />';
$output .= '</p>';
echo $output;
}
add_action('login_form', 'pwcn_add_math_problem_to_login');
/* 回答のチェック */
/* 計算に失敗したときに管理者にメールを送信 */
function pwcn_check_math_answer($user, $username, $password) {
// Nonceの検証
if (!isset($_POST['pwcn_login_math_nonce']) || !wp_verify_nonce($_POST['pwcn_login_math_nonce'], 'pwcn_login_math_nonce')) {
return new WP_Error('nonce_error', '無効なリクエストです。');
}
// トークンとユーザーの回答の検証
if (isset($_POST['pwcn_math_answer']) && isset($_POST['pwcn_math_token'])) {
$expected_answer = base64_decode($_POST['pwcn_math_token']);
//入力値が数値でない場合は排除するサニタイズ処理
$input_answer = intval($_POST['pwcn_math_answer']);
if ($input_answer != $expected_answer) {
// メール送信処理
//送信するメールの内容
$admin_email = get_option('admin_email');
$subject = 'ログイン時の計算問題認証に失敗しました';
$message = '計算問題の回答に誤りがあったか、空のままログインしようとしました。心当たりがない場合はスパム行為である可能性があります。';
wp_mail($admin_email, esc_html($subject), esc_html($message));
return new WP_Error('pwcn_math_error', '計算問題の解答が間違っています');
}
}
return $user;
}
add_filter('authenticate', 'pwcn_check_math_answer', 30, 3);
機能が追加できたことを確認できたら、サイトに合わせて表示する文字列の変更をするとよいでしょう。
コードの簡易解説
セキュリティに関わることですので、コード内容から行っていることが理解できることを前提に簡単に解説します。
まず最初のユーザー定義関数で計算問題をランダムに作成しています。
次のユーザー定義関数内で、ログインフォームへ計算問題の欄を出力しています。
その次のユーザー定義関数内で計算式の解答と実際に入力された値のチェックを行い、ログインできるかどうかを判断して処理しています。
その際nonce検証を使ってログインフォームから入力された値かを確認するようにしており、フォームを介さずにログインしようとした人(ブルートフォースアタックなど)をはじき出すことができるよう配慮しています
公式のプラグインで機能を追加したい方は
ログイン画面だけでなくもっといろいろなシーンで使用したい場合や、もっと複雑なロジックで計算による認証をしたいのであれば、以下のプラグインがいいかも知れません(テストや確認はしていません)。
コメントを残す