Email Verification Protocol (EVP / Chrome Origin Trial) への対応 — 会員登録のメール所有確認を省略
- Dominant language
- PHP
- Stars
- 788
- Forks
- 719
- Avg merge
- 3d 20h
- Merged PRs (30d)
- 45
Description
## 概要
Chrome が **Email Verification Protocol (EVP)** の Origin Trial を開始した(2026-07-08 公開)。
EVP は、メールアドレス所有確認を **OTP や magic link のようにユーザーをサイト外へ遷移させることなく**、
ブラウザ経由で完結させる新しい Web プラットフォーム機能。会員登録フローの離脱率低減が主目的。
- API 提案: https://github.com/WICG/email-verification (Browser Email Verification API)
- プロトコル仕様: https://github.com/dickhardt/email-verification / IETF draft `draft-hardt-email-verification-00`
- Origin Trial 解説: https://developer.chrome.com/blog/email-verification-protocol-origin-trial
本 issue は、EC-CUBE を **Verifier(メールアドレスを収集・検証する側)** として EVP に対応させるための調査・実装設計を扱う。
## 用語と役割
| 役割 | 説明 | EVP における該当 |
|---|---|---|
| **Verifier** | メールアドレスを集め検証するサイト | **EC-CUBE(本体)** |
| **Email Provider / Issuer** | メールサービス・アカウント管理側(例: gmail.com / accounts.google.com) | Gmail 等(EC-CUBE 側の実装不要) |
EC-CUBE が実装するのは Verifier 側のみ。Issuer 側(DNS `_email-verification` 委譲レコード・`/.well-known/email-verification` エンドポイント・issuance API 等)は **メールプロバイダーの責務であり EC-CUBE では不要**。
## 解決する課題
現状 EC-CUBE の会員登録は「仮会員 → 確認メール送信 → メール内リンク(`secret_key`)をクリックで本会員化」という**メール往復による所有確認**を行っている。
- `src/Eccube/Controller/EntryController.php`
- `index()` (mode=complete, L113-157): `BaseInfo::isOptionCustomerActivate()` が有効なら `MailService::sendCustomerConfirmMail()` で `entry_activate` リンク付き確認メールを送信
- `activate()` (`/entry/activate/{secret_key}/{qtyInCart}`, L188-) → `entryActivate()` (L227-265): `getProvisionalCustomerBySecretKey()` で仮会員を引き当て、Status を `PROVISIONAL` → `REGULAR` に更新
- `Customer::$secret_key`(ユニーク制約, `StringUtil::random(32)`, `CustomerRepository::getUniqueSecretKey()`)
この「メールを開いてリンクを踏む」往復がユーザー離脱の一因。EVP を併用すると、対応ブラウザ + メールプロバイダーにサインイン済みのユーザーは、**登録フォーム送信と同時にメール所有が確認済みとなり、確認メールの往復を省略できる**。
## Verifier(EC-CUBE)側の実装内容
### 1. 会員登録フォームへの EVP 属性付与
現状、email 入力欄に `autocomplete` 属性が付いていない。EVP は以下を要求する。
- email input: `type="email"` + `autocomplete="email"`
- EVT 受け取り用の hidden field: `autocomplete="email-verification-token"` + `nonce`(リプレイ防止のランダム値)
対象:
- `src/Eccube/Form/Type/RepeatedEmailType.php`(`EntryType` L73 の `email` フィールドが利用。`entry` / `mypage_change` 共有)
- `src/Eccube/Resource/template/default/Entry/index.twig` L111-125(`form.email.first` / `form.email.second`)
- 出力 name は `entry[email][first]` / `entry[email][second]`。**確認用の 2 入力(RepeatedEmailType)と EVP をどう両立させるか**(EVP 前提時は確認欄を省略できるか)は要検討。
```html
```
### 2. EVT(Email Verification Token)の検証
フォーム送信時に付与される EVT を EC-CUBE サーバ側で検証する。EVT は **SD-JWT+KB**(`~` 区切り)形式。検証手順(記事準拠):
1. **トークン解析**: SD-JWT+KB を分解(JOSE ライブラリ利用。PHP なら `web-token/jwt-*` 等)
2. **基本クレーム検証**: `email_verified === true` / `email` がフォーム入力と一致 / `nonce` が hidden field と一致 / `aud` が自サイトの origin と一致 / `iat` が直近のタイムスタンプ
3. **Key Binding 検証**: `cnf` クレームのブラウザ一時鍵と `sd_hash`(`sha256(evtJwt + "~")` の base64url)を照合
4. **DNS 検証**: email ドメインの `_email-verification.` TXT レコードから `iss=` を取得し Issuer を確定
5. **署名検証**: Issuer の `/.well-known/email-verification` から `jwks_uri` を引き、JWK で EVT の署名を検証(`signing_alg_values_supported` は `EdDSA` / `ES256` 等)
検証成功時は、その email を**所有確認済み**として扱い、会員登録で仮会員(`PROVISIONAL`)を経ずに直接本会員(`REGULAR`)化する分岐を追加する。
### 3. フォールバックと段階的導入
- **非対応ブラウザ / EVT 未付与 / 検証失敗 時は、既存の `secret_key` 確認メールフローに必ずフォールバック**する(EVP を必須にしない)。Origin Trial 段階かつトラフィック制限がある機能のため。
- 有効/無効を店舗設定(`BaseInfo` 相当のフラグ)で切り替え可能にする(`isOptionCustomerActivate()` と同様のパターン)。
- Origin Trial 参加には Verifier サイトごとの **OT トークン登録**が必要(`` またはレスポンスヘッダ)。本番投入前提でない旨を明記。
## 影響範囲(email を入力/検証する箇所)
EVP 適用を検討しうる箇所を洗い出し(会員登録が第一対象、他は将来検討):
- **会員登録**(第一対象): `EntryController` / `EntryType` / `RepeatedEmailType` / `Entry/index.twig`
- マイページ会員情報変更(メール変更): `Mypage/ChangeController.php`(`EntryType` 再利用、`isOptionMailNotifier()` で変更通知メール)
- お問い合わせ: `ContactController` / `Front/ContactType.php`(`EmailType` 単一入力)
- パスワード再発行: `ForgotController`(`reset_key` 別系統。所有確認の側面あり)
- ログイン: `CustomerLoginType`(`login_email`)
## 対応方針(提案)
- **フェーズ 1(本 issue の主眼)**: 会員登録フォームへの `autocomplete` 属性付与 + EVT 検証サービスの新設(`Eccube\Service` 配下、HTTP 非依存の検証ロジック)+ 既存メール確認フローへのフォールバック。設定フラグで opt-in。
- **フェーズ 2**: マイページのメール変更・お問い合わせ等への横展開。
- 実装は **`app/Customize` で完結しない**(コアの `EntryController` / フォーム / テンプレート改変を伴う)ため、コア機能として設計する。EVT 検証は独立した Service に切り出し、決済プラグイン等と同様に拡張・差し替え可能な seam を用意する。
## 注意事項・リスク
- **仕様が不安定**: EVP は Origin Trial 段階。`request_token` の署名方式が **HTTP Message Signatures**(`draft-hardt-email-verification`)へ移行予定など、後方互換のない変更が予告されている。Chrome の UX も更新予定。**GA 前に本機能へ依存しないこと**(トラフィック制限あり)。
- **標準化は 2 系統並行**: WICG の Browser Email Verification API と IETF draft。動向を追跡する。
- Verifier 側は Issuer の well-known / DNS を**参照する**のみ(自前で公開する必要はない)。
## 参考
- https://developer.chrome.com/blog/email-verification-protocol-origin-trial
- https://github.com/WICG/email-verification
- https://github.com/dickhardt/email-verification
- Origin Trial 登録: https://developer.chrome.com/origintrials
- デモ(Verifier): https://rowan.fyi/made/email-verification
Contributor guide
Research direction
Start by reading EntryController.php, EntryType, RepeatedEmailType.php, and Resource/template/default/Entry/index.twig to trace the current provisional-account and confirmation-mail flow. Review the referenced EVP, WICG, and IETF materials before deciding the verification boundary. Done means a documented phase-one design covering the opt-in flow, EVT validation seam, and reliable fallback without depending on the unstable protocol.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php, symfony
- Domain
- authentication, backend, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100