フォームに reCAPTCHA を導入してボットからのアクセスを遮断する


a-blog cms Ver.2.8.0から拡張機能より、GoogleのreCAPTCHA機能が使用できます。 ウェブサイトにアクセスを試みるボットを遮断するために設置されているreCAPTCHAですが一度はどこかで体験したことがあると思います。webのフォームは一番攻撃されやすい箇所になります。reCAPTHAを導入して、ロボットによるスパム投稿を防ぎましょう。


ロボットでないことを証明する

ロボットでないことを証明する


下準備

まずreCAPTCHAを導入するために、reCAPTCHA にアクセスして、必要な情報を取得します。

「Domains」の項目はご利用のサイトのドメインを指定してください。


(スクリーンショット)

サイトのドメイン登録


(スクリーンショット)

Site key と Secret key の取得


サイトを登録し、以下2つのキーを使用しますのでメモしておいてください。

  • Site key
  • Secret key

クライアント実装

下準備ができましたので、まずはクライアントサイドを実装します。

JavaScript

以下コードを ご利用のテーマのフォームの head要素内に読み込んでください。

例えば、simple2016テーマなら themes/simple2016/contact/index.html です。

<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<script>
  function validateRecaptcha ( code ) {
    if ( !!code ) {
      var form = document.querySelector(".recaptcha");
      form.removeAttribute('disabled');
    }
  }
</script>

HTML

次に送信フォームを少し修正します。simple2016テーマなら themes/simple2016/contact/form/main.html を開きます。

以下コードを送信フォーム内に挿入します。ここで、{Site key} は 下準備で取得した Site keyに置き換えてください。

<div class="g-recaptcha" data-callback="validateRecaptcha" data-sitekey="{Site key}"></div>

次に、送信ボタンに recaptcha クラスをふり、 disabled にしておきます。

<input type="submit" name="ACMS_POST_Form_Submit" value="送信する" id="btnSubmit" class="recaptcha btn-attention-block-large" disabled />

完成例

例として themes/simple2016/contact/form/main.html を編集しています。

<!-- BEGIN step#confirm -->
...

<form action="thanks.html" method="post" class="form-btn form-btn-send" enctype="multipart/form-data">

    <div class="g-recaptcha" data-callback="validateRecaptcha" data-sitekey="xxxxxxxxxxxxxxxxxxxxxx"></div>

    <input type="hidden" name="To[]" value="{email}" />
    <input type="hidden" name="AdminReply-To[]" value="{email}" />
    <input type="hidden" name="AdminFrom[]" value="{email}" />
    <input type="hidden" name="step" value="result" />
    <input type="hidden" name="takeover" value="{takeover}" />
    <input type="hidden" name="id" value="contactForm" />
    <input type="submit" name="ACMS_POST_Form_Submit" value="送信する" id="btnSubmit" class="recaptcha btn-attention-block-large" disabled />
</form>

クライアントサイドは完成です。実際に動かしてみましょう。フォームの確認画面まで行くと、reCAPTCHAが表示され、送信ボタンが押せないようになっているかと思います。reCAPTCHAで承認が通ると送信ボタンが押せるようになります。


(スクリーンショット)

チェックするまで送信ボタンが押せない


サーバーサイド実装

クライアントサイドの実装ができると、一見動いていそうに見えますが、このままだと送信ボタンの disabled を開発者ツールなどで削除してしまえば、送信できるようになってしまいます。そこで、サーバーサイドで認証を行いましょう。

認証の仕組み

ユーザーがreCAPTCHAの認証を通ると、ランダムな文字列のコードが生成され、フォーム送信時に一緒に送信されます。 このコードを使って、サーバーサイドでreCAPTCHAのapiにリクエストを投げ、正しいコードかチェックを行うことにより、正常な手段でフォームが送信されたことを確認することができます。

実装

実装にはHook機能を使います。php/ACMS/User/Hook.phpbeforePostFire に以下のコードを追加しましょう。

config.server.phpのHOOK_ENABLEを 1 にしておきましょう。

public function beforePostFire($thisModule)
{
    $moduleName = get_class($thisModule);

    if ( $moduleName === 'ACMS_POST_Form_Submit' ) {
        $secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx';
        $response = $thisModule->Post->get('g-recaptcha-response');
        $api = "https://www.google.com/recaptcha/api/siteverify?secret=${secret}&response=${response}";

        $valid = false;
        if ( $res = @file_get_contents($api) ) {
            $check = json_decode($res);
            if ( $check->success === true ) {
                $valid = true;
            }
        }

        if ( !$valid ) {
            $Field  = $thisModule->extract('field');
            $Field->setMethod('g-recaptcha-response', 'check', false);
            $thisModule->Post->set('step', 'forbidden');
        }
    }
}

ここで、 $secret を、下準備で用意した Secret key で置き換えます。これで実装は完了です。

確認

では実際に、サーバーサイドで認証ができているかチェックしてみましょう。フォームで確認画面まで移動して、 disabled になっている送信ボタンを、開発者ツールで disabled を外して送信してみましょう。以下の画像のようにサーバーサイドで不正なアクセスとして処理されていることが確認できます。


不正なアクセスとして処理される

不正なアクセスとして処理される

メディア機能の画質改善をしました


2022年1月6日 にリリースされたVer. 3.0.2でメディア機能でアップロードした画像の画質改善を行いました。 今回はこの画質改善について詳しく紹介します。

画質劣化する原因

まずメディア機能は以下のような手順でアップロード・表示をおこなっています。

  1. 編集画面で画像を選択
  2. 大きい画像でもアップロードできるように、ブラウザでリサイズ処理(canvas使用)
  3. アップロード処理
  4. PHPで画像生成(Imagick or GD)
  5. テンプレート解決時、resizeImg校正オプションがある場合、再度画像生成(Imagick or GD)
  6. 表示

ここで画質劣化に影響を与えているのは、2番目のブラウザのリサイズ処理です。

メディア機能では、一眼レフカメラで撮ったままの画像のようなサイズの大きい画像をそのままアップロードしてしまうと、 サーバーの制限に引っかかるため、ブラウザ側でリサイズしてからアップロードしています。

このブラウザでのリサイズ機能が、うまくダウンサイズできず、ノイズやジャギーが目立ってしまい画質が劣化していました。 ただし全ての画像で起きるわけではなく、以下のような条件だと発生しやすいです。

画質劣化しやすい画像

元画像のサイズが大きく、ブラウザでのリサイズサイズと差が大きい場合、劣化しやすくなる

ブラウザでリサイズするサイズは、コンフィグ > 編集設定 の「拡大表示時の最大サイズ」で指定します。 「拡大表示時の最大サイズ」と、元画像のサイズの差が小さければ、あまり画像劣化は発生しません。

改善前と改善後の検証

Ver. 3.0.2 で ブラウザでのダウンサイズの方法を修正しました。
ここでは実際に修正前と修正後でアップロードされた画像を数枚比較してみてみます。

今回の画像は、十分大きな画像(横5000px 以上)から、ブラウザで1400pxにリサイズし、サーバー側(PHP)で、1200px にリサイズした画像となります。

1枚目(全体)左:修正後  右:修正前

v3.0.2 v.2.11.42

いかがでしょうか。この写真の場合、全体表示ではパッとわからないかもしれません。
髪の毛の部分がわかりやすいので、次は同じ画像をズームしたもので検証してみます。

1枚目(髪の毛部分をズーム)左:修正後  右:修正前

v3.0.2 v.2.11.42

髪の毛の部分のノイズや、ジャギーが目立たなくなっていると思います。

2枚目(全体)左:修正後  右:修正前

v3.0.2 v.2.11.42

こちらも全体だと少しわかりにくいので、わかりやすい街灯部分をズームしてみます。

2枚目(街灯部分をズーム)左:修正後  右:修正前

v3.0.2 v.2.11.42

どうでしょうか。街灯周りや空のノイズが、修正前は多く出ていたのが、修正後は抑えられていると思います。

3枚目(全体)左:修正後  右:修正前

v3.0.2 v.2.11.42

こちらも全体だと少しわかりにくいので、顔部分をズームしてみます。

2枚目(顔部分をズーム)左:修正後  右:修正前

v3.0.2 v.2.11.42

髪の毛やメガネのフレーム、服のパターン部分がわかりやすいと思います。やはり修正前は、ノイズやジャギーが目立っていますが、修正後は抑えられています。

ブラウザでリサイズを行わないオプション

画像比較どうでしたでしょうか。修正後は、ノイズやジャギーが抑えられて画質が向上していると思います。 ただ気づかれた人もいるかもしれませんが、ブラウザのリサイズを行うと改善後の画像でも、若干シャープネスが甘くなり画質劣化が起こります。

どうしてもブラウザでリサイズを行うと多少の画質劣化が起きてしまうため、今回ブラウザでのリサイズ機能を使用しないオプションを用意しました。

設定方法

private/config.system.yaml に以下記述をします。

media_client_resize: off

注意事項

このオプションを設定すると、大きなサイズの画像がアップロードできなくなります。なので手作業で画像をリサイズしてからアップロードしなければならず、 多少の手間と知識が必要となります。

以上になります。いかがでしたでしょうか。
高い画質クオリティが求められる場合も多いと思います。 一度いろいろ試してみていただけると幸いです。

引き続き皆様のお役に立てるよう、改善を進めてまいります。 今後ともどうぞよろしくお願いいたします。

Ver.3.0.0で行なった主なプロダクトのUI改善


こんにちは。デザイナーの森田です。

この記事では、Ver.3.0.0にて行った主なプロダクトのUI改善の取り組みをご紹介します。
大きな変更ではありませんが、一部見た目や文言に若干の変更を加えています。

Ver.3.0.0 で改善した主なこと

  • 各一覧ページで空のステータスを用意
  • モジュールIDのURLコンテキストに複数選択のアイコンを追加
  • 承認機能の文言を見直し

ほかにも微修正した部分がありますが、この記事では以上の改善点について詳しくお知らせします。

各一覧ページで空のステータスを用意



データの件数が空だった時も以前までは検索フィルターと表の一部が表示されている状態でしたが、場合によってはローディング画面のようにみえてしまうことを懸念し、現在が空の状態がわかるように改善しました。

一部の機能では、空の状態を伝えるとともに次のアクションを示唆しています。たとえばエントリー管理のデータが0だったとき、新規作成ボタンのみ表示されます。

同じ変更が加わった機能

  • エントリー管理
  • 承認通知
  • 承認履歴一覧
  • カテゴリー管理
  • コメント管理
  • ゴミ箱
  • フォーム管理
  • 投稿データ
  • モジュールID管理
  • ロール一覧
  • ルール管理
  • スケジュール管理
  • ショートカット管理
  • タグ管理
  • ユーザー管理
  • ユーザーグループ一覧
  • Webhook管理


モジュールIDのURLコンテキストに複数選択のアイコンを追加



視覚情報で複数選択できることが伝わるよう、複数選択が可能な項目ではアイコンを表示しています。
モジュールIDの引数では、モジュールの種類によってはIDが複数選択できる箇所とできない箇所がありますが、以前までは見た目では区別ができない状態だったため改善を行いました。

承認機能の文言を見直し



承認機能使用中のコミュニケーションを円滑にするために、文言に変更を加えました。

  • メッセージが改行可能に
  • 「承認依頼」から「承認する」または「承認依頼する」へ変更
  • 「却下」から「差し戻す」へ変更

メッセージが改行可能に

どのような変更を加えたのか記述する際に長文を書いても相手に読みやすく配慮したメッセージが送れるよう改善しました。

「承認依頼」から「承認依頼する」または「承認する」へ変更

以前まではエントリーを書いたユーザーも、そのエントリーを承認するユーザーも「承認依頼」というラベルのボタンでしたが、ユーザーの文脈を考慮して改善を行いました。
エントリーを作成したユーザーが承認依頼をするときは「承認依頼する」、承認を行うユーザーの場合は「承認する」ラベルが適用されます。

「却下」から「差し戻す」へ変更

以前までは「却下」という文言を使用していた部分について「差し戻す」という文言へ変更しました。「提案をしりぞける」以外にも「一部分の修正をお願いしたい」という意味合いで従来の却下機能を使うこともあり、実際のアクションの意味合いよりも強い意味合いを印象付けることへ配慮しました。

たとえば、エントリーを書いたユーザーに送っているメール通知の文言は以下のように変更しています。

変更前
申請が却下されました。 [323:テスト / draft:バージョン2]

変更後
承認依頼が差し戻されました [323:テスト / draft:バージョン2]

メール本文のレイアウト変更

メール本文は見出しと内容を視認しやすくなるよう、レイアウトを再検討しました。


改善後はタイトルが詳細情報と区別され、主要なコンテンツであるコメントとそのほかの項目でグルーピングされている

改善前と改善後のレイアウトの比較


最後に

ほかにも微調整を行なった箇所はありますが、今回はそのなかでも大きなものやユーザーの皆様のお役に立ちそうな点をご紹介しました。
Ver.3.0.0の機能面のリリース内容に関しては別途リリースノートをご覧ください。

引き続きみなさまのWeb制作のお役に立てるよう、システム・サービスの向上に取り組んでまいります。 今後とも、a-blog cms のことをよろしくお願いいたします。