- ベストアンサー
セッションを使ったログインページでのエラー
前にもセッションを使ったログインページについて質問したものです。 上記の通りセッションを使ったログインページを作っております。 前回このソースを載せたときセキュリティー的にとても危険だというご意見をいただきました。何分まだ初心者ですのでどうかご了承ください。 ソース /*ログインのページは省略しました。ログイン後ID・パスワードが正しいか、そして訪問者がログインせずにこのページに直接アクセスした際にログインページにジャンプするようにするようにするプログラムです*/ <?PHP if (!isset($user) || !isset($pass)) { header( "Location: loginPage.php" ); } elseif (empty($user) || empty($pass)) { header( "Location: loginPage.php" ); } else { $user = addslashes($_POST['username']); $pass = md5($_POST['password']); $dbHost = "localhost"; $dbUser = "*****"; $dbPass = "*****"; $dbDatabase = "mysql"; $db = mysql_connect("$dbHost", "$dbUser", "$dbPass") or die ("Error connecting to database."); mysql_select_db("$dbDatabase", $db) or die ("Couldn't select the database."); $result=mysql_query("select * from users where username='$user' AND password='$pass'", $db); $rowCheck = mysql_num_rows($result); if($rowCheck > 0){ while($row = mysql_fetch_array($result)){ session_start(); session_register('username'); echo 'Success!'; header( "Location: checkLogin.php" ); } } else { echo 'Incorrect login name or password. Please try again.'; } } ?> このようなプログラムを作ったのですが、ちゃんとパスワードをいれても、ちゃんと認証されずに、ログインのページ戻されてしまいます。 おそらく if (!isset($user) || !isset($pass)) { header( "Location: loginPage.php" ); } elseif (empty($user) || empty($pass)) { header( "Location: loginPage.php" ); } の部分がおかしいのかと思いますがどう変えたら良いのかよく分かりません。また、おかしいと思った部分を削除したら普通にログインはできるのですが、今度は一度ログインしても他のページに移動した後もう一度このページに行くと、もう一度ログインしないとアクセスできなくなりました。 まとめると、お聞きしたいことは、2つです。 (1)紹介したのプログラムでログインしてもちゃんとログインが認証されない。これを解消するにはどうすればいいのか? (2)ユーザーがログインした後もう一度このページにアクセスした場合もう一度ログインさせなくてもいいようにすればどうすればよいのか。 もし可能でしたら、解決するためのプログラムを(さらに可能でしたら紹介したプログラムを生かした形で)添えてアドバイスしていただけないでしょうか?よろしくお願いいたします。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
テストしてないのでアレですが、こんな感じかな? 思いつきで書いたので、書き間違いバグなどあるかも。 デバッグだけのためなら die() でいいですが、表にだすなら、真っ白にこの文字だけというのはかっこわるいので、”アクセスできません”的な専用のページにリダイレクトした方がいいと思います。 ログインフラグの変数など勝手に書き換えてしまいましたが、参考になれば幸いです。 ------------------------ <?php // リダイレクト専門関数 function redirect($url){ header("Location: ".$url); exit; } // セッション開始 session_start(); // 値が送信されてるか確認 なければ差し戻し if(empty($_POST['username']) || empty($_POST['password'])) redirect("loginpage.php"); // 値げっと $user = $_POST['username'];// 文字種を絞ってるなら preg_matchなどで確認も $pass = md5($_POST['password']); $dbHost = "localhost"; $dbUser = "*****"; $dbPass = "*****"; $dbDatabase = "mysql"; $db = mysql_connect("$dbHost", "$dbUser", "$dbPass") or die ("Error connecting to database."); mysql_select_db("$dbDatabase", $db) or die ("Couldn't select the database."); $result=mysql_query("select * from `users` where `username`='".mysql_real_escape_string($user)."' AND `password`='".mysql_real_escape_string($pass)."'", $db); $rowCheck = mysql_num_rows($result); // マッチしなければ 差し戻し ログインページで $_GET['error']=="no" なら ”IDかパスワードが違います”と表示 if(empty(rowCheck)) redirect("loginpage.php?error=no"); // 認証成功 $row = mysql_fetch_array($result)); $_SESSION['login']=true;// ログイン済みとする // そのほか必要な処理 // チェックページへ移動 redirect("loginPage.php" ); ?>
その他の回答 (3)
- SHlVA
- ベストアンサー率48% (20/41)
if (!isset($user) || !isset($pass)) { header( "Location: loginPage.php" ); } この後に empty でも確認してるので、↑のコードはなくてもいいかも。 session_start() はできるだけ、コードの一番最初に宣言した方がいいです。headerも同様ですが、これらの前に何か出力されるとエラーになります。setcookieもね。また、header("Location: XXX") としても、その後のコードも処理されてしまいムダになるので、その後にexit;を加えればすぐにリダイレクトされます。 個人的なものですが、session_registerでセッション変数にするより、$_SESSIONを使った方が見た目にもわかりやすかったりします。 思ったような処理にならないときは、いつも変数に何がはいっているのか確認することをお勧めします。最初の $userの節がおかしいなら、$userや$passに何が入っているのかを確認すべきです。またフォームから送られてきた内容も同時に確認するといいです。var_dump($_POST) など。 addslashesよりmysql_real_escape_string(MySQLの場合)のほうが適しています。 と、前置きはこれくらいで。 (1)について、おそらく、今回の原因は他の方もおっしゃるようにregister_globals=offによる$userが空になっていることだと思われます。その後に$_POST['username'],$_POST['password']とあるので、おそらくこれらが炉群ページから入力された値かと思います。これらの値を最初に確認すべきで$userや$passではないですね。 (2)について、このページは原則としてまだログインしてない人のための処理ですから、ログイン済みの人の場合は、最初に他のページにリダイレクトしたほうがいいかもしれません。もしくはログアウト処理をするか。ログインページも同様。ログイン済みの人でもログインページにアクセスすればまたフォームが表示される、となればログアウト状態だと勘違いしてしまいます。
- masa6272
- ベストアンサー率66% (93/140)
$user = $_GET['user']; $user = $_GET['pass']; とかを、書いてから$userを使えば、O.K.です。 前のページで、postで渡しているなら、$_GETの代わりに、$_POSTを使います。 不明でしたら、$_REQUESTで持ってこれますが、この変数は、post、get、cookieの値をまとめて持ってきます。送信データ偽造が比較的楽なので、あまりお勧めしません。 後、このプログラム・・・ headerの前にechoしてますが・・・ これは、ワーニングになります。 ワーニングといっても、遷移しないんで、実質エラー・・・orz headerは、HTMLのデータを送る前に送る必要があります。 headerの前には、空白1文字、改行1つも送ってはいけません。
- masa6272
- ベストアンサー率66% (93/140)
php.ini の設定で、register_globals がoffになっていると思います。 PHP4.2以後では、offが規定値です。 この場合、$user、$passにフォームの値は入りません。 なぜ、規定値がoffになっているかについては、参考URLを見てください。 前の、ページでpostで渡しているならば$_POST['name']、$_POST['pass']、getで渡しているならば$_GET['name']、$_GET['pass']で取り出せます。 $_REQUSTは、post、get両方に対応していますが、はっきりさせるために$_GET、$_POSTを使うことをお薦めします。
補足
ご解答ありがとうございます。 どうやら私がやっていたのはもうすでに古いバージョンの奴みたいですね。いろいろインターネットで調べてみてるのですが、どれが新しいバージョンを使った例なのか古いバージョンでの例なのかがよく分かりません。 もし現在のバージョンを使ってログイン認証のページの作り方を載せてるサイトをご存知でしたら教えていただけないでしょうか?