a-blog cms の 拡張アプリ「reCAPTCHA for a-blog cms」を使うと、GoogleのreCAPTCHAを使用してボットからの フォームアクセスを防御することが出来るようになります。
利用するためには最新リリースから zip をダウンロード後、解凍して extension/plugins に設置してください。
- extension/plugins/ReCaptcha
- a-blog cms: Ver. 3.0.x – 3.2.x (3.3+ not tested yet)
- PHP: 7.2.5 – 8.4 (8.5+ not tested yet)
管理ページ > 拡張アプリより「拡張アプリ管理」のページに移動します。そのページより下の図のようにreCAPTCHAをインストールします。
config.server.php で HOOK_ENABLE を有効にしておく必要があります。
define('HOOK_ENABLE', 1);まずreCAPTCHAを導入するために、reCAPTCHA にアクセスして、必要な情報を取得します。
ReCAPTCHA V3 を選択し、Domainを登録します。
Site key と Secret key をコピーしてメモしておきます。
- Site key
- Secret key
管理ページ > reCAPTCHA に移動し、Site key と Secret key を設定します。
お問い合わせフォームに reCAPTCHA を適用するには、以下の手順を行います。
管理ページ > フォーム に移動し、reCAPTCHA を利用したいフォームIDから reCAPTCHA連携 を有効にします。
以下コードをフォームテンプレートの head 要素内に読み込んでください。
<!-- BEGIN_MODULE Admin_InjectTemplate id="recaptcha-js" -->
<!-- END_MODULE Admin_InjectTemplate -->
このモジュールにより、Google reCAPTCHA API スクリプトと recaptcha.js が自動で注入されます。キャッシュバスティング用のクエリも自動的に付与されます。
Admin_InjectTemplate を使わずに直接書くこともできます。ACMS.Config.ReCaptcha を設定する既存のコードも引き続き動作します。
<!-- BEGIN_MODULE ReCaptcha -->
<script src="https://www.google.com/recaptcha/api.js?render={sitekey}"></script>
<script src="/extension/plugins/ReCaptcha/assets/recaptcha.js"></script>
<script>
if (window.ACMS === undefined) {
ACMS = {};
ACMS.Config = {};
ACMS.Config.ReCaptcha = '{sitekey}';
} else {
ACMS.Ready(function () {
ACMS.Config.ReCaptcha = '{sitekey}';
});
}
</script>
<!-- END_MODULE ReCaptcha -->
フォーム送信時(確認画面)の form 要素を修正します。
form 要素の class 属性に js-recaptcha-form クラスを追加します。
<form action="thanks.html" method="post" enctype="multipart/form-data" class="js-recaptcha-form">
...
<input type="submit" name="ACMS_POST_Form_Submit" value="送信する"/>
</form>
reCAPTCHA によってロボットだと認識された場合は、Form モジュールの step#forbidden ブロックが表示されます。
<!-- BEGIN step#forbidden -->
<p>不正なアクセスです。</p>
<!-- END step#forbidden -->
フォームの確認画面まで行くと、reCAPTCHA のロゴが右下に表示されていると思います。実際にフォームを送信して、送信できるか確認しましょう。
reCAPTCHA 拡張アプリ Ver. 3.1.0 以降では、フォームだけでなく 会員ログイン・会員登録・パスワードリセット・2段階認証リカバリー などの認証フォームにも reCAPTCHA を適用できます。
- 対象ページを管理画面の設定で有効にするだけで機能します
- reCAPTCHA スクリプト(Google API + recaptcha.js)は対象ページの
</head>直前に 自動で注入 されるため、テンプレートへの JavaScript 記述は不要です - 検証に失敗した場合は IllegalAccess エラーとして処理されます
管理ページ > reCAPTCHA に移動し、適用したいフォームのチェックボックスを有効にして保存します。
会員機能の設定
| 設定項目 | 対象モジュール | コンフィグキー |
|---|---|---|
| サインイン認証 | ACMS_POST_Member_Signin |
google_recaptcha_member_signin |
| 会員登録 | ACMS_POST_Member_Signup_Submit |
google_recaptcha_member_signup |
| パスワードリセット | ACMS_POST_Member_ResetPassword |
google_recaptcha_member_reset_password |
| 2段階認証リカバリー | ACMS_POST_Member_Tfa_Recovery |
google_recaptcha_member_tfa_recovery |
ACMS_POST_Member_Signinを継承するMember_SigninWithEmail(認証メール送信)/Member_SigninWithVerifyCode(確認コード入力)も自動的に対象となります。Member_Tfa_Auth(2段階認証コード入力)は id/pass 認証済みのステップのため除外されます。
管理ログイン機能の設定
| 設定項目 | 対象モジュール | コンフィグキー |
|---|---|---|
| ログイン認証 | ACMS_POST_Member_Admin_Login |
google_recaptcha_member_admin_login |
| パスワードリセット | ACMS_POST_Member_Admin_ResetPassword |
google_recaptcha_member_admin_reset_password |
| 2段階認証リカバリー | ACMS_POST_Member_Admin_Tfa_Recovery |
google_recaptcha_member_admin_tfa_recovery |
ACMS_POST_Member_Admin_Loginを継承するAdmin_LoginWithEmail(認証メール送信)/Admin_LoginWithVerifyCode(確認コード入力)も自動的に対象となります。Admin_Tfa_Auth(2段階認証コード入力)は id/pass 認証済みのステップのため除外されます。
認証機能の設定
| 設定項目 | 対象モジュール | コンフィグキー |
|---|---|---|
| ログイン認証 | ACMS_POST_Login_Auth |
google_recaptcha_login_auth |
| 会員登録 | ACMS_POST_Login_Subscribe |
google_recaptcha_login_subscribe |
| パスワードリセット | ACMS_POST_Login_Remind |
google_recaptcha_login_remind |
| 2段階認証リカバリー | ACMS_POST_Login_Tfa_Recovery |
google_recaptcha_login_tfa_recovery |
有効な設定がある場合、プラグインが対象ページの </head> 直前に以下を自動で挿入します。
<script src="https://www.google.com/recaptcha/api.js?render={sitekey}"></script>
<script id="acms-recaptcha-js" src="{recaptcha.jsのパス}" data-sitekey="{sitekey}"></script>サイトキーは data-sitekey 属性で recaptcha.js に渡されます。recaptcha.js のパスにはキャッシュバスティング用のクエリが自動で付与されます。テンプレート側でのスクリプト読み込みは不要です。
reCAPTCHA の検証に失敗した場合、ACMS_GET_SystemError モジュールの IllegalAccess ブロックが表示されます。
認証フォームのテンプレートに SystemError モジュールを配置し、IllegalAccess ブロックを定義してください。
<!-- BEGIN_MODULE SystemError -->
<!-- BEGIN IllegalAccess -->
<div role="alert" class="acms-alert acms-alert-danger acms-alert-icon">
<span class="acms-icon acms-icon-attention acms-alert-icon-before" aria-hidden="true"></span>
不正なアクセスです。
<button type="button" class="js-acms-alert-close acms-alert-icon-after" aria-label="アラートを閉じる">×</button>
</div>
<!-- END IllegalAccess -->
<!-- END_MODULE SystemError -->SystemError モジュールは他のシステムエラー(CSRF トークン切れなど)にも使われるため、以下のようにすべてのブロックをまとめて定義したテンプレートを include として使い回すのが一般的です。
<!-- BEGIN_MODULE SystemError -->
<!-- BEGIN IllegalPostData -->
<div role="alert" class="acms-alert acms-alert-danger acms-alert-icon">
<span class="acms-icon acms-icon-attention acms-alert-icon-before" aria-hidden="true"></span>
送信データが不完全です。
<button type="button" class="js-acms-alert-close acms-alert-icon-after" aria-label="アラートを閉じる">×</button>
</div>
<!-- END IllegalPostData -->
<!-- BEGIN CsrfTokenExpired -->
<div role="alert" class="acms-alert acms-alert-danger acms-alert-icon">
<span class="acms-icon acms-icon-attention acms-alert-icon-before" aria-hidden="true"></span>
ページの有効期限が切れています。
<button type="button" class="js-acms-alert-close acms-alert-icon-after" aria-label="アラートを閉じる">×</button>
</div>
<!-- END CsrfTokenExpired -->
<!-- BEGIN DoubleTransmission -->
<div role="alert" class="acms-alert acms-alert-danger acms-alert-icon">
<span class="acms-icon acms-icon-attention acms-alert-icon-before" aria-hidden="true"></span>
連続送信は禁止されています。
<button type="button" class="js-acms-alert-close acms-alert-icon-after" aria-label="アラートを閉じる">×</button>
</div>
<!-- END DoubleTransmission -->
<!-- BEGIN IllegalAccess -->
<div role="alert" class="acms-alert acms-alert-danger acms-alert-icon">
<span class="acms-icon acms-icon-attention acms-alert-icon-before" aria-hidden="true"></span>
不正なアクセスです。
<button type="button" class="js-acms-alert-close acms-alert-icon-after" aria-label="アラートを閉じる">×</button>
</div>
<!-- END IllegalAccess -->
<!-- END_MODULE SystemError -->




