質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

1回答

9485閲覧

ページをリロードするとsubmitされている?

SugiuraY

総合スコア317

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2019/06/12 13:27

下記のようなformを設置しているlogin.phpがあるのですが、
if($login_username==""||$login_pw=="")のようにサーバーサイドでも入力がない場合に
バリデーションをかけてエラーメッセージを吐き出すようにしています。

ここで、本ページ上に諸々の操作をした後にページを更新(リロード)すると<?php var_dump($_POST);?>
値がリフレッシュされておらずリロード=submitのような挙動を示していることがわかりました。

本来の動作としては
if((/リロードではなくformをsubmitした場合/) && ($login_username==""||$login_pw==""))
と言う形で処理させたいのですが、このように動作してしまう原因と解決方法がわかりません。

調べたところ、このような記事を見つけました。
原因はブラウザ側の仕様とされているのですが詳細は載っていなく、また対処法の
if($_POST['submit']) {
/* 処理 */
header("Location: {$_SERVER['PHP_SELF']}");
exit;
}
についてもどの要素にname="submit"を設定すれば意図した動作なのかがわからず、解決に至ることができませんでした。buttonタグ等にname="submit" value="XX"等を設定しても、結局リロードがsubmitのような挙動をするので
実際にPOSTでもリロードでも$_POST['submit']は"XX"を返すので意図した動作になりません。

お力添えをお願い申し上げます。

php

1<form id="login" class="login-form" action="xx.php" method="POST"> 2 <input type="hidden" name="login" value="login_catch"> 3 <input type="hidden" name="token2" value=<?php echo htmlspecialchars($_SESSION['token2'],ENT_QUOTES,"UTF-8")?>> 4 <input type="text" name="loginname" id="login_username" class="register_text" placeholder="ユーザ名"/> 5 <input type="password" name="loginpw" id="login_pass" class="register_text" placeholder="パスワード"/> 6 <button form="login" class="login_button" type="submit" name="btn" value="check">ログインする</button><!--20190118--> 7 <div class="login-errmsgbox"> 8 <?php var_dump($_POST);?> 9 <?php if($login_username==""||$login_pw=="")){ 10     echo'<p id="er1" class="errmessage">メールアドレスとパスワードを記入して下さい</p>'; 11 }/*here*/?> 12 </div> 13 <p class="message message_wrapper" tabindex="0">無料でアカウントを作成する</p> 14</form>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

リロードで再送信するのはformの仕様といっても良いです。

この多重送信(サブミット)という現象、よくあるのがセッションを利用した対策です。
「ワンタイムトークンを発行し、そのトークンと照合する」というのが概要。

下記のような記事を参考に対応してみてください。

投稿2019/06/12 14:25

m.ts10806

総合スコア80765

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SugiuraY

2019/06/12 23:42

コメントありがとうございます。 朝一で調べて、設定したトークンをSESSIONとPOSTに格納し、POSTされた時とreloadされた時にそれぞれ挙動を確認しながら実装することができました。本当にとても勉強になりました。感謝いっぱいでございます。 もし、後学のために最後にアドバイスをいただきたいのですが、 1) 自分は調べた結果tokenの生成を以下のようにしているのですが、現代PHPにおいてこれは実務的なのでしょうか、または他の方法を採るべきでしょうか? $bytes = openssl_random_pseudo_bytes(16); $_SESSION['token']=bin2hex($bytes); 2)想定していた、バリデーションが実装できたのですが、全て通過した場合、以下のような処理を入れようと思うのですが、$_SESSIONの特定変数の破棄と言う意味ではこれで十分かと思っているのですが、実際には$_COOKIEについても削除することが望ましいのでしょうか?あくまで本tokenに紐づくsessionidを削除する目的でという点だけにfocusした話ではありますが。たまたまそのような記事を見つけたのでケースによってかと思いますが、実務上はどのようにされているのかが気になりました。(https://www.flatflag.nir87.com/session-528#i-6) *他のユーザー情報等をブラウザに残すために実際にはtokenのセッションだけを切り離すためにcookieを削除することはあまり現実的ではないきがするのですが、考え方自体が的外れであった場合は申し訳ございませんが、ご放念ください。 //バリデーションの通過サーバー処理 unset($_SESSION['token])//格納したtokenの初期化
m.ts10806

2019/06/12 23:57

1 「ワンタイムトークン」なので、私見ではありますが、同一セッション内で重複しない文字列が生成できれば生成方法にベストプラクティスというのはないと思います。 色々と現場を見てきましたがネットで検索して最初に出てくるような記事をそのまま採用しているパターン、独自のロジックを採用しているパターン、様々ありました。 今はフレームワークで標準に提供している機能を利用することが多いかなと思いますが、それも現場次第でしょう。 2 $_COOKIEは内容確認してみましたか?ひとまず対象だけunsetでいいと思います。
退会済みユーザー

退会済みユーザー

2019/06/13 00:09

本件における token の役割は「POST の一意性を確保する」ことです。一意性のみが要件です。 多重 submit のことだけを考えるのであれば、ただの「連続した数字を配布する」ことですら実現可能です。 ただ、「CSRF 対策の token」と兼ねているケースも多いと思います。その場合、要件としてはそちらの方に引っ張られます。 で、そうなると、コメントの質問内容は全く別のものとなるので、質問し直したほうが良いです。
m.ts10806

2019/06/13 00:11

確かに、一意性確保だけならtime()の値だけでも良いですね。
SugiuraY

2019/06/13 01:17

mts10806様 te2ji様 コメントを頂きありがとうございます。図らずも自分もCSRF対策を兼ねて使用しているトークンで実装したのでなるほどなるほどというところでした。 仰る通り、趣旨が異なってくるので、必要あらばまた別の質問として、その点はお尋ねしてみようと思います。 いずれにしても大変勉強なりましたので、新ためて深謝を申し上げます。 宜しくお願いいたします。
SugiuraY

2019/06/13 01:19

あ、アイコンが変わっていて気が付きませんでしたが、お茶どうぞのmts10806様でしたね。 いつもお力添え有難うございます。
m.ts10806

2019/06/13 01:20

>お茶どうぞの たぶん2代くらい前のアイコンですね。 やはりアイコンで認識されている人も多いんですね・・。 とはいえ、諸々あって今のアイコンも切り替え検討中です。 まあ、問題解決する際にあまり誰がどうというのは関係ないとは思いますので、 そのあたりは内容のみで勝負したいなと(とはいかない人も中にはいるので難儀ですが)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問