現在プログラムの勉強をしている者です。
現在、お問い合わせフォームの作成を行っていまして
送信時に「トークン認証」を行って、不正な投稿ではないかのチェックを行っているのですが
自力で解決できない問題が発生してしまいました。
【現象】
html側に仕込んでいるトークンと
PHP側のトークンを検証して、一致していたら処理を実行、不一致ならエラーが表示というものを
ドットインストールさんや書籍・ネットで調べて試してみたのですが
初回時に限り「トークンの認証失敗」が必ず起きてしまいます。
原因を探る為にhtml側を見てみた所、
初回時に限って
html
1<input type="hidden" name="token" value="<br /> 2<b>Notice</b>: Undefined index: token in <b>
このようにトークンがありませんという風に表示されていました。
エラーで失敗になった2回目からは
html
1 <input type="hidden" name="token" value="a05a840362109ee44b661e97326447ae"> 2 <input type="submit" value="送信" class="btn btn-primary"> 3
このように表示されていまして
トークンの認証もきちんと問題なく出来ていました。
そこで、最初からhtml側にトークンを表示させていればトークンの認証失敗が起きないのでは?と考えて
色々試してみたのですが上手くいきませんでした。
下記が書いたコードです。
//PHP // postなら処理を実行する if($_SERVER['REQUEST_METHOD']==='POST'){ if (!isset($_SESSION['token'])) { $_SESSION['token'] = bin2hex(openssl_random_pseudo_bytes(16)); } if ( !isset($_SESSION['token']) || !isset($_POST['token']) || $_SESSION['token'] !== $_POST['token'] ) { throw new \Exception('トークンの認証に失敗しています。もう1度、お問い合わせのメッセージの送信を試してみてください。'); } else { //トークン認証成功時に行う処理です。 $otoiawasename = h($_POST['toiawase_name']); $otoiawaseemail = h($_POST['toiawase_email']); $otoiawasebody = h($_POST['toiawase_body']); $sql = "insert into otoiawase (name, mail, otoiawase, created) values (:name,:mail,:otoiawase,now()) ON DUPLICATE KEY UPDATE created = now() "; $stmt = $db->prepare($sql); $stmt->execute([ ':name' => $otoiawasename, ':mail' => $otoiawaseemail, ':otoiawase' => $otoiawasebody ]); } header('Location:http://test.com/abut2.php'); } //HTML <form class="form-horizontal" action="" method="post" style="margin-bottom:15px;"> <div class="form-group"> <label class="control-label" for="email">お名前</label> <input type="text" name="toiawase_name" class="form-control" placeholder="お名前"> </div> <div class="form-group"> <label class="control-label" for="email">Email</label> <input type="email" name="toiawase_email" class="form-control" required placeholder="Email"> </div> <div class="form-group"> <label class="control-label" for="email">内容</label> <textarea name="toiawase_body" class="form-control" maxlength="1000" minlength="5" required cols=40 rows=10></textarea> </div> <div class="form-group"> <input type="hidden" name="token" value="<?php echo h($_SESSION['token']); ?>"> <input type="submit" value="送信" class="btn btn-primary"> </div> </form>
安易に初めから
$_SESSION['token'] = bin2hex(openssl_random_pseudo_bytes(16));
こちらを「POST時の条件判定」よりも前に書いて
最初から$_SESSION['token']に入れてみた所、
htmlのソースには初回時からトークンが表示されましたが、
今度はPOST時のトークン認証で不一致となりエラーが表示されてしまいました。
実行結果:
echo $_SESSION['token']; 結果: cb9b04d3cc2549b8b5207d8fed231468 echo $_POST['token']; 結果: aa70c6aced1c45390e625a3df47a2a9c 不一致となってしまいまいsた。
解決方法をご存知の方や
コードの間違いに気づかれた方がいらっしゃいましたら
お力をお貸し頂けると、とても嬉しいです。
どうかよろしくお願いします。
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2017/12/16 10:54
2017/12/16 11:13