プロが教える店舗&オフィスのセキュリティ対策術

下記のようなプログラムにてユーザー認証&リンク先の振り分けを考えているのですが、上手に出来ません。どこか問題がありましたら教えていただけないでしょうか?エラー構文などは出ないのですが、フォーム上からユーザーIDとパスワードを入力してもうまくページが切り替わらず、同じログインフォームのページが開いてしまうのです。

<?php
//
$data_file = "d_file.dat"; //データファイルの指定
$authlevel = 0; //権限レベル
if($action == "post"){
$p_data = file($data_file);
$p_flag = 0;
for($i=0; $i<count($p_data); $i++){
list($id,$pass,$authlv) = split(",", $p_data[$i]);
if($id == $u_id && $pass == $passwd){
$authlevel = $authlv; //権限レベルを読む
$p_flag++;
}
}
if($p_flag > 0){
switch (authlevel){
case 1:
require ("http://www.dell.com");
break;
case 2:
require ("http://www.whitehouse.gov");
break;
case 3:
require ("http://www.yahoo.com");
break;
case 4:
require ("http://www.google.com");
break;
case 5:
require ("http://www.yahoo.co.jp");
break;
default://上記以外
require ("http://www.kantei.go.jp");
break;
//echo "<CENTER><BR><BR><BR><FONT COLOR='blue'>おめでとうございます。あなたは正式に認証されました。<BR><BR>\n";
//echo "ここにお好きなHTML表示を埋め込んで下さい。</FONT>\n";
}
} else {
echo "<CENTER><BR><BR><BR><FONT COLOR='red'>ユーザーIDとパスワードが間違っています。やり直して下さい。</FONT>\n";
}
}
?>

ちなみに、パスワードファイル(d_file.dat)には
(ユーザーID),(パスワード),(権限レベル),
と記述したファイルを用意しました。

A 回答 (8件)

スクリプトがうまく動かない場合は、論理的に考える事と、それぞれの変数が期待通りになっているかを一つ一つ確認してく事で原因がわかります。




同じログインフォームが表示されるという事は
if($p_flag > 0){
ここでelseになってるという事ですよね。恐らく$p_flagが0のままなのでしょう。

ではなぜ$p_flagが0のままなのかと言うと

if($id == $u_id && $pass == $passwd){
この行が一向にtrueにならないから、と予測されます。

ここまで考えたら、後は$id,$u_id,$pass,$passwdをprint文などで表示させてみましょう。

恐らく原因は$u_idと$passwdが空なのではないかな、と推測します。もし空になっていましたら、$u_idと$passwdを$_GET["u_id"]$_GET["passwd"]または$_POST["u_id"]$_POST["passwd"]と書き換えてみて下さい。

なお質問のテーマではありませんが、他のサイトに飛ばす場合
header ("location: URL");
exit();
とする方が適切だと思います。まあ、サンプルなのでこう書いているだけだとは思いますが。

この回答への補足

ご回答ありがとうございます。
全くの初心者で難しいことをしようとしているので、見当違いの事を聞いてしまうかもしれないのですが、
ご指摘の箇所を改善するのにどのようにすればいいか、正直なところわかりません。
他のサイトに飛ばす部分の
header ("location: URL");
exit();

これについては、

switch (authlevel){
case 1:
header ("location: http://www.dell.com");
exit();
break;

ということなのでしょうか?
このレベルのことからわからない状態です。

補足日時:2005/06/25 01:46
    • good
    • 0

switch (authlevel){


の部分は$authlevelでは?


フォームのu_id やpasswdは取得できていますか?
確認の為にechoで表示してみては?
もしできていないようであれば、
import_request_variables("p", "");
を記述してみてはいかがでしょうか。

この回答への補足

お答えありがとうございます。
冒頭のご指摘の部分を書き換えましたところ、

Parse error: parse error, unexpected T_CASE in /usr/home/~/public_html/(ファイル名).php on line 130

という風に出てしまい、書き換えたところのParse errorとなってしまいました。

また、echoでフォーム部分を書くのは難しいと思い、普通のWEB制作ソフトで作ったhtmlに提示したプログラムを貼り付け、拡張子をphpに変えただけです。
import_request_variables("p", "");
を記述する方法もわかりません。ネットで調べてみたのですが、やはり具体的なサンプルがないので…。
import_request_variables("p", "");
↑をどこに付け足せばいいのでしょうか?

補足日時:2005/06/25 01:50
    • good
    • 0

No1です。

初心者という事で、恐らくうまく動かないことばっかりだと思うんですね。で、動かない時にいちいち聞いていては恐らく全然進まないと思うんですよ。ですから、動かない時にどうするか、どういう考え方をするのか、という視点で書いたつもりだったんですが、ダメでしたか(^^;。

ベテランでも書いたスクリプトが一発で動くことなんて少ないんです。一発で動かなくて、一つ一つ現象を調べながら動くようにしていくんです。ですから、どんなスクリプトでも動かなくて当然、それを動くようにする事が一番大事な作業だって考えて下さいね。

さて、取り急ぎやって頂きたい事はまず

switch (authlevel){

ここですね。質問を書き込む時の単なるミスタイプだと思って触れなかったんですが、switch($authlevel){としないと$authlevelの内容を見ている事にはなりません。そこを修正してエラーが出たという事ですが、何かミスタイプなどをしているのだと思います。よく見直して下さい。このエラーの原因は「文法違反」です。カッコの数が合わない、"や'の対応がおかしい、などなどのミスタイプが原因です。

次に一番最初でいいですから、
print "u_id=".$u_id."<br>\n";
print "passwd=".$passwd."<br>\n";
の2行を入れて下さい。$u_id,$passwdという2つの変数は、ログインフォームから受け渡される変数ですよね?この2つの値が正常に受け渡されているかどうかを調べて下さい。正常に受け渡しができていれば、内容が表示されます。もし何も表示されなければ、フォームからのデータがスクリプトに届いていません。

僕の推測では恐らくここが空なのではないかな、と思っています。その場合、No2さんのご指摘のimport_request_variablesでとりあえず対処しておきましょう。
import_request_variables ("gp","");
の1行を一番頭におまじないだと思って入れて下さい。

これで動いたらバンザイですね。もし動いたら、参考URLのNo5の回答を読んでみて下さい。

参考URL:http://okweb.jp/kotaeru.php3?q=1462496

この回答への補足

お答えありがとうございます。しかし出来ませんでした。

下記のとおりプログラムを直してみました。

<?php
//
import_request_variables ("gp","");
$data_file = "(d_file.datのある場所をフルパスで)"; //データファイルの指定
$authlevel = 0; //権限レベル設定
if($action == "post"){
$p_data = file($data_file);
$p_flag = 0;
for($i=0; $i<count($p_data); $i++){
list($id,$pass,$authlv) = split(",", $p_data[$i]);
if($id == $u_id && $pass == $passwd){
$authlevel = $authlv; //ここで権限レベルも読み込みます
$p_flag++;
}
}
if($p_flag > 0){
switch($authlevel){
case 1:
header ("location: http://www.dell.com");
exit();
break;
case 2:
header ("location: http://www.whitehouse.gov");
exit();
break;
case 3:
header ("location: http://www.waseda.jp");
exit();
break;
case 4:
header ("location: http://www.google.com");
exit();
break;
case 5:
header ("location: http://www.yahoo.co.jp");
exit();
break;
default://ない筈だけど万が一を考えて・・
header ("http://www.kantei.go.jp");
exit();
break;
//echo "<CENTER><BR><BR><BR><FONT COLOR='blue'>おめでとうございます。あなたは正式に認証されました。<BR><BR>\n";
//echo "ここにお好きなHTML表示を埋め込んで下さい。</FONT>\n";
}
} else {
echo "<CENTER><BR><BR><BR><FONT COLOR='red'>ユーザーIDとパスワードが間違っています。やり直して下さい。</FONT>\n";
}
}
?>
教えていただいたように、
print "u_id=".$u_id."<br>\n";
print "passwd=".$passwd."<br>\n";
を入力すると、ブラウザでphpファイルを開けば、u_id=、
passwd=、
というものが表示され、IDとパスワードを入力してから送信ボタンをクリックすると、フォームに入力したIDとパスワードが表示されるようになりますが、やはり依然としてページは切り替わらず、同じフォームが表示されてしまいます。

補足日時:2005/06/26 04:09
    • good
    • 0

動きませんか。

でもこれ以降もやる事は一緒です。原因と思われる事を推測して、一つ一つ変数の中身を確認していくだけです。実際今回のテストで、フォームからの値が正常に受け渡されている事がわかりました。原因が一つ潰れたわけです。これは一歩前進です。これを繰り返していくだけです。

if($action == "post"){
$p_data = file($data_file);
$p_flag = 0;
for($i=0; $i<count($p_data); $i++){
list($id,$pass,$authlv) = split(",", $p_data[$i]);
if($id == $u_id && $pass == $passwd){
$authlevel = $authlv; //ここで権限レベルも読み込みます
$p_flag++;
}
}

このパートの$actionって何の変数ですか?フォームから$actionっていう変数で何か値を渡しているんですか?そしてそれは"post"という文字列で間違いはないですか?だとしたら前回と同じように

print "action=".$action."<br>\n";

として、"post"が入ってるか確認して下さい。

同じように変数の中身が疑わしい部分を表示させて、期待通りの値になっているかどうか確認して下さい。

この回答への補足

お世話になっております。
今回もご指摘のとおり、print文にて $actionの変数の動作について確認をしてみました…が、
今度はフォーム上でIDとパスワードを入力しても何も表示されませんでした。
これが、何をしようとしている変数なのか、ということは、正直わかりません(・・;)
というのも、このオリジナルソースももはや連絡が取れないある方に作ってもらったものなので、
自分で何を意図して一つ一つの構文を打っているかは全くわからずにそのままコピペしていったのです。

補足日時:2005/06/26 15:16
    • good
    • 0

本来、このタグ



<input type="HIDDEN" name="action" value="post">

この値を見ているのだと思いますが、この上の行に</form>があるので、このactionの値はフォームの値として送られていません。なので、</form>の上にこの行を移すか、あるいはif($action == "post"){の分岐自体を省いてしまうかでこのセクションは解決すると思います。

この回答への補足

お付き合い、本当にありがとうございます。
いろいろ編集してがんばっているのですが、
パスワードファイルにないユーザーIDとパスワードを入力した場合、

「echo "<CENTER><BR><BR><BR><FONT COLOR='red'>ユーザーIDとパスワードが間違っています。やり直して下さい。</FONT>\n";」

の構文で表示されるはずの、

「ユーザーIDとパスワードが間違っています。やり直して下さい。」(赤い文字)

↑の表示が出来るようにはなりました。
しかし、正しいIDとパスワードを入力しても振り分けのリンクが出来ず、パスワードが間違っていれば赤い字で表示される部分に、たとえば、権限1の人のユーザーIDとパスワードを入れた場合、

「Warning: Cannot modify header information - headers already sent by (output started at /usr/home/free/home/(ウェブスペースアカウント名)/public_html/members_login_PC2.php:5) in /usr/home/free/home/(ウェブスペースアカウント名)/public_html/members_login_PC2.php on line 132」と表示されます。

ちなみにphpファイルの131行目~134行目は
case "1":
header ("location: http://www.dell.com");
exit();
break;

となっています。
ページをリンクさせる構文が違うという意味なのでしょうか。

補足日時:2005/06/26 17:35
    • good
    • 0

>「Warning: Cannot modify header information - headers already sent by (output started at /usr/home/free/home/(ウェブスペースアカウント名)/public_html/members_login_PC2.php:5) in /usr/home/free/home/(ウェブスペースアカウント名)/public_html/members_login_PC2.php on line 132」と表示されます。



OK、じゃあ認証自体はうまく行ってますね。header関数の前に文字出力が既にされているとこのエラーが出ます。恐らくデバッグ用のprint文を全て外せば解決すると思います。

requireでなくてheader関数(リダイレクトって言います)をお薦めしたのは、技術的な問題よりも、一般的でないような気がするというか、考えようによっては他のサイトの内容を自分のサイトとして表示するような事にならないかな、と思っただけです。requireを使うと、指定したURLをソースの一部として取り込むという意味合いになります。閲覧者から見れば、違うURLを入力しているのに他のサイトの内容が表示されるという事になってしまうので、著作権の問題などが発生する可能性もあるんじゃないかな、といった印象を受けました。

この回答への補足

実はすでにprint文は全てはずしてあります。

フォームとかもechoを使って書いていないからページ自体が切り替わらないのでしょうか。
次に考えられるのはどの箇所なのでしょうか…。
もう自分はちんぷんかんぷんの状態です。

header関数についてもphpのサイトでちょっと見てみましたが、とりわけ誤っているようには思えませんでした。(初心者の見たまんまでしたが…)

補足日時:2005/06/27 02:56
    • good
    • 0

確かにこれだとそのエラーが出ますね。



判定をする部分を冒頭に持ってきて、判定にひっかからない場合にフォームが表示されるように直せば良いと思います。このスクリプトだと判定が上手くいってもいかなくてもフォームが表示されてしまいますよね?

この回答への補足


概略を書くと、アカウントとパスワードを権限が割り振られているものを入力し、フォームから送信すると、フォームは消えるのですが、ページが白い背景になり、その上で、

Warning: Cannot modify header information - headers already sent by (output started at /usr/home/free/home/(省略)/members_login_PC2.php:5) in /usr/home/free/home/(省略)/members_login_PC2.php on line 33

こういったエラーメッセージがやはり表示されてしまいます…

補足日時:2005/06/27 17:41
    • good
    • 0

拝見しましたが、まだこれは冒頭ではありませんね。

header関数の前に画面出力があってはならないんです。これはタグはもちろん、改行であっても同じです。

そもそもリダイレクトする際にはHTMLの出力は一切必要ないのですから、HEADERブロックも不要です。

<html>
<head>
<title>動作すればいいなぁ</title>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<style type="text/css">
<!--
.six { font-size: 6pt}
.seven { font-size: 7pt}
.eight { font-size: 8pt}
.nine { font-size: 9pt}
.ten { font-size: 10pt}
-->
</style>
</head>

このブロックをBODYタグの前に移せば良いでしょう。
    • good
    • 0
この回答へのお礼

思い通りの動作ができました。
これでようやく完成です。

お忙しい中お付き合いいただき本当にありがとうございました。
今まではいただいたソースというものをそのまま使っていただけでしたが、今回、この状況を通して、自分なりに勉強が出来たと思います。

本当にありがとうございました。
感謝してもしきれません…。ありがとうございました。

お礼日時:2005/06/27 18:10

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!