実現したいこと
会員登録画面からメールアドレスに認証コードを送りたい。
発生している問題・分からないこと
以前お問い合わせページを作成した際に CSRF対策として入力画面からワンタイムトークンを作成して、確認画面でそのトークンが一致するかどうかをチェックするという仕組みを作成したのですが、会員登録画面(入力画面)からメールアドレスに送るタイミングでワンタイムトークンを作成してチェックするということは可能でしょうか?
該当のソースコード
HTML
1<div class="login-email"> 2 <form method="post" class="register_form"> 3 <div class="form_item"> 4 5 <!-- <div class="login-inputWrapper"></div> --> 6 <!-- hiddenで生成したトークンを埋め込む --> 7 <!-- oninputプロパティは一定時間操作が無かったら処理を実行させる関数 --> 8 <input type="hidden" id="input-email" name="csrf_token" maxlength="15" oninput="value=value.replace(/[^\d]/g, '')" placeholder="メールアドレスを入力してください" value="<?= $csrf_token; ?>"> 9 10 <div id="error-msg-email" class="error-msg" style="display: none;"></div> 11 12 <div class="login-email_vertical-line"></div> 13 <div class="login-email-send clickable disabled"> 14 <font style="vertical-align: inherit;"> 15 <font style="vertical-align: inherit;">認証コードを取得する</font> 16 </font> 17 </div> 18 </div> 19 20 <div class="form_separator-line"></div> 21 <div class="form_item"> 22 <div> 23 <font style="vertical-align: inherit;"> 24 <font style="vertical-align: inherit;">ハンドルネーム</font> 25 </font> 26 </div><input placeholder="ハンドルネームを入力してください" maxlength="6" oninput="value=value.replace(/[^\d]/g, '')"> 27 </div> 28 29 <div class="form_separator-line"></div> 30 <div class="form_item"> 31 <div> 32 <font style="vertical-align: inherit;"> 33 <font style="vertical-align: inherit;">検証コード</font> 34 </font> 35 </div><input placeholder="確認コードを入力してください" maxlength="6" oninput="value=value.replace(/[^\d]/g, '')"> 36 </div> 37 <input type="hidden" name="csrf_token" value="<?php echo $csrf_token; ?>" /> 38 <!-- ↑追加 --> 39 <!-- </div> --> 40 </form> 41 </div>
PHP
1<?php 2$_SESSION = array(); //セッション変数の初期化 3session_start(); //セッションの開始 4 5// 変数の宣言 6// $error_message = ''; 7$mail = ''; 8 9// エラーが発生している時の処理 10/* if (!empty($_SESSION['error_message'])) { 11 $error_message = $_SESSION['error_message']; 12 unset($_SESSION['error_message']); 13} */ 14 15// ワンタイムトークン生成 16$toke_byte = openssl_random_pseudo_bytes(16); 17$csrf_token = bin2hex($toke_byte); 18 19// トークンをセッションに保存 20// トークンを保存、次の画面(PHP)に持ち越し 21$_SESSION['csrf_token'] = $csrf_token; 22 23// ワンタイムトークンの一致を確認 24// name属性「csrf_token」の中身が無い、または name属性「csrf_token」とセッション「csrf_token」が一致しない場合 25if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) { 26 // トークンが一致しなかった場合 27 die('送信に失敗しました'); 28} 29 30// それぞれの変数に値を代入 31// PHPの値が空であれば 32if (!empty($_SESSION['mail'])) { 33 $mail = $_SESSION['mail']; 34 // セッション変数を削除 35 unset($_SESSION['mail']); 36} 37 38// ハンドルネームをメールで送信 39if (!empty($_SESSION['name'])) { 40 $name = $_SESSION['name']; 41 // セッション変数を削除 42 unset($_SESSION['name']); 43} 44 45// 確認コードをメールで送信(6桁) 46if (!empty($_SESSION['code'])) { 47 $_SESSION['code'] = rand(100000, 999999); 48 // セッション変数を削除 49 unset($_SESSION['code']); 50} 51?>
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
今後サーバーサイドでセキュリティ対策となるコードを書いていく際に確認画面を設けない場合にメールアドレスに直接送信する方法では攻撃を防ぎきれないのではないかと心配しております。
補足

回答2件
あなたの回答
tips
プレビュー