【ECCUBE2】スパム対策としてお問合せフォームにreCaptchaを導入

定期的に中国から来る迷惑なお問合せフォームを利用したスパム。

スパムの一例↓

このように、メールアドレス欄に不特定多数のメールアドレスを指定し、自動返信機能を利用してメールを送り付けている。

今までは接続元IPを特定して、apacheの設定ファイルなり.htaccessで個別にアクセスを拒否するなど、対症療法をしていましたが、業務の負担になりつつあるので、導入することにしました。

結果として効果はかなりあったようで、対策後およそ1か月、未だスパムによる被害は1回もうけていません。

reCaptchaをECCUBE2のお問合せフォームに導入する手順は以下の通りです。

サイトキーとシークレットキーの取得

  1. reCaptchaにアクセスし「Admin console」を開きます。Googleアカウントが必要になります。
  2. 必要事項を入力し、サイトキーとシークレットキーを取得します。(今回は「」を採用します。)

テンプレートを修正

ECCUBE2のお問合せフォーム(確認画面)のテンプレートファイルを修正します。

スマホページも運用している場合はそちらのテンプレート(data/Smarty/templates/sphone/contact/confirm.tpl)も同様に修正します。

PHPファイルの修正

お問い合わせの受付・自動返信メール送信処理を行うPHPファイルを修正します。

確認

確認画面の右下に、以下のようなreCAPTCHAアイコンが表示されていれば、適用完了です。

 

参考サイト)

 

【ECCUBE2】外部からのPOSTでセッションが切れる件の対応

2020年4月に入ったあたりから、ECCUBE2を使用している内部サービスで、決済代行会社の決済画面から戻った際になぜかセッションが無効となり、ページ遷移エラーもしくは自動ログアウトしてしまう現象が発生。

原因は結果的に、chrome80からのCSRF(クロスサイトリクエストフォージェリ)対策として、Cookieセット時にSameSite属性が適切に指定されていない場合、外部からそのサイトにPOSTなどでアクセスされた際に発行されたサイトのCookieが強制的に無効になるという仕様によるものでした。(エンジニアが気づいた)

※なお、多くの混乱を招いたようで、直後のChromeアップデートで当仕様は取り急ぎロールバックされた模様

Googleからのアナウンスは、2019年11月には出ていた模様で、4月に入ったあたりから徐々にクライアントのChromeが80に強制アップデートされたようです。

現実に多くのショッピングサイトでは、決済時に決済代行会社の決済画面(特にリンクタイプ)で決済を行った後、処理結果受け取りのために決済完了画面からPOSTで戻って、パラメタを処理しています。

ECCUBE2のなどのカートシステムなどを利用している場合、大抵はページ遷移チェックがかかるため、この時決済画面に行く前のCookie情報が削除されていることから、セッション情報が判定できず、ログイン状態が無効となりセッションエラーもしくはログアウトという結果になります。

こういったサイトでは、対策として、

  • Cookie発行時に「SameSite=None; Secure」をセットする
  • httpsを利用する

ことで対応できます。

こちらに詳しくまとめていただいている方がいるので、適宜参照していただければと思います。

ECCUBE2のついては、すでにパッチが配布されていますで、ECCUBE2のサイト管理者は至急対応されることをおススメします。

なおこの配布パッチを充てると、具体的には、

  1. Cookieセット時に「SameSite=None;」を併せてセットする。この時、httpsなら「 Secure」を追加する
  2. SameSite=Noneが未対応のブラウザ用に、あらかじめ互換用のCookieを発行しておく。
  3. ECSESSIDが 現Cookieと対応しない場合は ECSESSID の Cookie が拒否されたと見なす
  4. 3の場合はあらかじめ発行しておいた互換用 cookie からセッションデータを読み込む

といった動作を行うようになります。

 

今回のアップデートについて、告知はされていたものの、もう少し具体的に影響を受ける対象事業者に対して大々的に告知してほしかったというのが正直なところ。

さらに言えば、決済代行会社も情報を早めに得て、影響を受ける顧客に周知するべきだったと思います。(リンクタイプを使っているクライアントはかなりいると思うし、、、)

うちが使っている決済代行会社は、通常結構この辺はきっちりしていて、こういう件が発生するときはかなり早めに連絡がくるのですが、今回に限ってはまったくもってノーマークだったように思います。念のため問い合わせたときに「特に障害情報は出ていません。どのような不具合でしょうか?」のような対応でしたからねー。

ECCUBE3でフォームの入力制限文字数を変更する

例えば、管理画面の何かしらのメニューでURL情報を入力するとき、stext_len(50文字)だと足りない時があるので、mtext_len(200文字)に変更する。

 

これらの値($config[‘***’])は”/src/Eccube/Resource/config/constant.yml.dist”で定義されている。

ちなみに以下、文字数制限の主要なデフォルト値。

ECCUBE3 独自パラメタで検索→リスト表示の時にサブタイトルにパラメタ名を反映させる

前提条件いろいろ割愛しますが、DBに当該データが入っていて、Doctrineファイルにパラメタと名前が定義してあり、Formビルダー各パラメタが構築されてるのが前提です。

以下ファイルを修正。

/src/Eccube/Controller/ProductController.php

基本、$searchDataに値が入っていれば、getName->()でとれます。

 

Joomla1.5でdescriptionにtitleの値を設定する

Joomla1.5とかって古っ!!という意見は置いておいて、、。

主にGoogleのSEO対策です。

Joomlaでは、ページのdescriptionが明示的に指定されていないと、グローバルのdescriptionの値が出力されます。

なので、descriptionの指定が無いページは、すべてdescriptionの内容が同じになって、Google先生にサーチコンソールとかで、「HTMLの改善:descriptionの重複!」と怒られます。

Joomlaで書き溜めた何百件もある記事、これから1件1件descriptionを書き足すのはかなり大変ですので、descriptionにはtitleの内容を動的に出力させ、Google先生の警告を回避するという横着な方法です。

1./templates/使用中のテンプレート名/index.phpを開きます。

2.以下のように修正します。

 

以上です。

 

ECCUBE3の商品一覧の並び順に「お気に入り数順」を追加する

  • まず最初に、並び順テーブル(mtb_product_list_order_by)に新しく「お気に入り数順」を追加

(一例)
・id:4
・name:お気に入り数順(任意)
・rank:3

※optionの順番を前に持ってきたければrankの番号を減らす

 

  • /src/Eccube/Resource/config/constant.yml.dist に追加したorderbyパラメタの番号(4)に名前を定義する

参考)
https://github.com/EC-CUBE/ec-cube/issues/2703

 

  • /src/Eccube/Repository/ProductRepository.php に、SQLを定義する

※クエリビルダーを使用する際、JOINするテーブル名やカラム名はdoctrineの定義に基づくので、 /src/Eccube/Resource/doctrine/Eccube.Entity.CustomerFavoriteProduct.dcm.ymlなどの中を確認して、同じ名前にする。

ちなみに、上記は、生のSQLとしては下記のような感じとなる。多分。

 

参考)
https://xoops.ec-cube.net/modules/newbb/viewtopic.php?topic_id=17472&forum=10
https://ameblo.jp/withathena/entry-12173872626.html
https://umebius.com/eccube/sort_admin_product_master/
http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/reference/query-builder.html
https://teratail.com/questions/30434
https://teratail.com/questions/43888
http://www.aiship.jp/knowhow/archives/25107
http://d.hatena.ne.jp/Fivestar/20100423/1272013815

 

以上で、商品一覧ページのドロップダウンに「お気に入り数順」が追加され、選択するとお気に入りに追加された数の多い商品順にソートされる。

ECCUBE3(Symfony)のテンプレート(Twig)内でのシステムURL出力

忘備録として随時更新中。テンプレ内をよく探せば出てくるのだが、、、。

 

  • トップページURL

 

  • カレントページ(現在アクセスしているページ)URL

 

  • 商品一覧ページURL

 

  • 商品画像保存ディレクトリの絶対パス

 

  • 商品詳細ページURL

 

  • 商品詳細ページでのメイン画像URL (Pinterestボタンに画像URLのパラメタ付けたい時とか)

 

参考サイト)

 

ECCUBE3でカテゴリに補足情報を追加する

EC-CUBE 3.0.16
MySQL 5.6.19
PHP 5.6.36

例として、あるカテゴリに「関連A」(assoc_A)という補足情報を追加する場合。

1. テーブルへのカラム追加
dtb_categoryテーブルへ”assoc_A”という名前のカラムをtinyintタイプで追加。また、NULLを許可にする。

2. エンティティファイルに、セッターゲッター追加
/src/Eccube/Entity/Category.php

以下のように追記。

 

3. データベース定義ファイルへカラム追加
/src/Eccube/Resource/doctrine/Eccube.Entity.Category.dcm.yml

fields一覧にassoc_Aの項目を追加。データベースとエンティティクラスを接続するのがdcm.yml(Doctrineマッピングファイル)。これにより、Categoryエンティティのassoc_Aとdtb_categoryのassoc_Aカラムが接続される。

※データ型がint,smallint,tinyintでも、Formでcheckboxタイプを使う予定のため( 論理型(値が1か0のタイプ)と認識されるので)ブーリアンタイプにしておく。

ECCUBE3で使用できるtype一覧は過去記事参照

 

4. フォーム定義ファイルへの項目追加
/src/Eccube/Form/Type/Admin/CategoryType.php

下記のように、管理画面の商品登録フォームへ定義を追加。

 

5. 管理画面(カテゴリ登録画面)へフォーム表示
/app/template/admin/Product/category.twig

フォームを表示したい場所に下記のように記述。

 

6. 商品詳細ページへの表示
/app/template/default/Product/detail.twig

関連付けした情報を使って詳細ページでごにょごにょするには、多少の工夫が必要。これについては別途書く予定。

とりあえず以上。

 

参考URL)

 

 

ECCUBE3で商品に新しい項目を追加

EC-CUBE 3.0.16
MySQL 5.6.19
PHP 5.6.36

例として、商品名かな(name_kana)という項目を追加する場合。

1. テーブルへのカラム追加
dtb_productテーブルへ”name_kana”という名前のカラムをtextタイプ(またはvarchar)で追加。また、NULLを許可にする。

2. エンティティファイルに、セッターゲッター追加
/src/Eccube/Entity/Product.php

以下のように追記。

 

3. データベース定義ファイルへカラム追加
/src/Eccube/Resource/doctrine/Eccube.Entity.Product.dcm.yml

fields一覧にname_kanaの項目を追加。データベースとエンティティクラスを接続するのがdcm.yml(Doctrineマッピングファイル)。これにより、Productエンティティのname_kanaとdtb_productのname_kanaカラムが接続される。

ちなみに、EC-CUBE3が採用しているSymfonyの標準ORM、Doctorineで設定できるフィールドタイプは以下の通り。

 

4. フォーム定義ファイルへの項目追加
/src/Eccube/Form/Type/Admin/ProductType.php

下記のように、管理画面の商品登録フォームへ定義を追加。

上記の書き方で入力必須とならない場合(未入力で保存した際にエラーとならない)場合は、下記のようにする。

 

なお、フォームの入力形式として整数型としたい場合は、第2引数に”integer”, 浮動小数点型としたい場合は、第2引数に”number”を指定するなどして対応。

このほかにも選択型(choice型)も指定できる。詳細は公式ドキュメントを参照。

 

5. 管理画面(商品情報登録画面)へフォーム表示
/app/template/admin/Product/product.twig

フォームを表示したい場所に下記のように記述。

form_rowは、form_label、form_widget、form_errorsを同時に出力する関数。テキストの入力幅を小さくしたい場合などは、form_label、form_widget、form_errorsに分割するなどしてCSSで対応。

 

6. 商品詳細ページへの表示
/app/template/default/Product/detail.twig

フロント側で出力。好きな場所に下記のように記載。未登録であれば何も出力されない。

 

以上。

 

参考URL)