hoge.phpからhoge_run.phpにデータをPOSTしています。
hoge_run.phpではupdateなどのSQLを発行しているので、
1)hoge.php以外から何らかの形でアクセスしても跳ね除ける
2)hoge_run.phpでリロードを禁止する。
というようにしたいのですが、PHPもしくはJavaScriptを使って抑制する方法はないでしょうか。
そういった、ユーザの誤動作防止のTipsをまとめているページがあればありがたいです。
http://www.tryhp.net/dynamic02.htm
CGIに役立つJavaScript
二回以上、送信ボタンを押されないようにすることはJavascriptで可能です。参照URLを見てください。また、hoge.phpの方でチェック用のhiddenタグを<input type=hidden name=check_flag value=”****”>のようにして持たせておいて、この「***」はユニークなものにしておけば、hoge_run.phpで$check_flagをテーブルなどに記録しておきます。もし、同じ値の「***」が飛んできたら二重送信(リロードもしくは二回submitボタンクリックなど)であると分かります。
また、何が何でもhoge.phpからのアクセスしか認めないということであれば、refererをチェックすればよいですが、refererは偽装できる上に、Norton Internet Securityを使っている人はrefererが空白になりますので、いろいろと問題になります。
http://service1.symantec.com/SUPPORT/INTER/nisjapanesekb.nsf/jp_...
参照元 (リファラ) が遮断され、Web サイトが正しく表示されない (Norton Internet Security 2003/Norton Personal Firewall 2003)
http://jp2.php.net/manual/ja/ref.session.php
PHP: セッション処理関数(session) - Manual
Tipsのページは知らないので1と2の件だけ回答します。セッションを使うことでサーバ側で対処できると思われます。概要だけコードで。
・hoge.phpにアクセスした段階で
$_SESSION[’hoge_run’] = 適当な値;
などとする。
・hoge_run.phpの先頭で、
if(isset($_SESSION[’hoge_run’]))
{
unset($_SESSION[’hoge_run’]);
do_db_transaction($_POST);
} else{
die(” 禁止されたアクセスです ”);
}
とする。
このコードなら$_SESSION[’hoge_run’]を設定するのがhoge.phpだけであれば1の条件を満たし、2に関してもhoge_run.phpを再度開こうとすると$_SESSION[’hoge_run’] はすでに消されているので die()でメッセージが出て止まるかと思います。セッションはregister_globalsの設定有無やPHPのバージョンによってアクセス方法が違うのでお使いの環境を調べてから使うかどかの判断をしたほうがいいと思います。
ありがとうございます。
この方法で行こうかと思います。
1. refererを取得してどこから遷移してきたかの情報を得る
hoge.phpから遷移してきたのみ実行できるようにする
2. session変数にhoge.phpが任意の値を代入する
その変数の値をみて正しいなら実行するようにする
3. hoge_run.phpをhoge_run.incなど拡張子を変える
include文でhoge_run.incをインクルードする
拡張子がincのファイルを隠すよう.htaccessなどで設定する
(apacheを利用の場合)
ありがとうございます。
http://www.shtml.jp/htaccess/referer.html
.htaccessで参照元(Referer)によるアクセス制限する方法
1)は、REFERERと.htaccessの組み合わせである程度は跳ね除けることは可能です。
が、REFERERは偽装も可能であることと、ファイヤウォール(ウィルスソフト)で
フィルタがかかってしまう場合があるので万能とはいえませんが。
ちなみに
$linkurl= $_SERVER[”HTTP_REFERER”];
という記述で、リンク元のURL文字列が取得できますので、
REFERERが取得できる場合に限っては、”
”以外は
跳ね除けるという記述になります。
http://www.scollabo.com/banban/php/php_14.html
セッション管理/PHP入門
2)のリロード禁止は、JavaScript等を使用してもなかなか難しいと思われます。
hoge.phpに簡易的にhiddenパラメータ(カウンタ)を埋め込みHTML出力し、hoge_run.phpを呼ぶごとにカウンタを加算していけば、リロードされたかの判定は可能です。
ただ、SQLの結果を返すタイミングのみは正しく反映したいと思いますので、そういう場合には、sessionとクッキーを使うというのではダメでしょうか?
単純にリロードされてしまった場合は、SQLの結果が返らなくても良いというのであれば前者で充分かと思います。
ありがとうございます。
hoge.phpからアクセスをはねる場合、スーパーグローバル変数を使って、リクエスト元を判断してはいかがでしょう?
リロード対策はデータをPOSTする場合、自分はワンクッション置く方法を取っています。
処理の順番としては、こんな感じです。
1.hoge.phpからhoge_run.phpへPOSTでデータを渡します。
2.hoge_run.phpではSQLの実行を行う。
3.hoge_run.phpの一番最後(文法上は最初でも可能)で処理完了画面へ飛ばすために、header(”Location:hoge_end.php”);を記述します。
こうすると、ブラウザの履歴はhoge.php→hoge_end.phpと解釈してくれるので、中間のhoge_run.phpが戻るボタンを押してもリロードされる心配はありません。
ちょっとわかりにくいかもしれませんが、試してみてください。
なるほど、これもありですね。
ありがとうございます。
uniqの利用もいいですね。