0

さまざまなチュートリアルに従い、オンラインの記事を読んで、ログイン/登録システムをゼロから作成しました。システムは動作しますが、理解できないバグがあります。ユーザーが初めてログインしようとすると、アカウントが見つからないというエラーが返されますが、ユーザーが再度ログインしようとすると、ログインが続行されます。セッション Cookie が保存されているかどうかをテストしたところ、そうではありません(少なくとも初めてではありません)。次回ユーザーがログインを試みると、Cookie が適切に保存されます。

これはログイン スクリプトの最初の部分です。入力されたキャプチャが正しいかどうかを確認し、セッション Cookie を設定して、ユーザーが存在するかどうかを確認するログイン ページ スクリプトにユーザーをリダイレクトします。

<?php
 session_start();
 $mode = $_GET['mode'];
 if($mode == 'login')
 {
     require_once('recaptchalib.php');
    $privatekey = "---";
    $resp = recaptcha_check_answer ($privatekey,
                                 $_SERVER["REMOTE_ADDR"],
                                 $_POST["recaptcha_challenge_field"],
                                 $_POST["recaptcha_response_field"]);
    if (!$resp->is_valid) {
    // What happens when the CAPTCHA was entered incorrectly
        header('Location: http://cpalander.net/login.php?option=captcha');
    } else {
        $user = $_POST['username2'];
        $pass = $_POST['password3'];
        $_SESSION['pass3'] = $pass;
        $_SESSION['user3'] = $user;
        header('Location: http://cpalander.net/login.php?option=checkuser');
    }
    die();
 }
 else if($mode == 'sendticket')
 {
     require_once('recaptchalib.php');
    $privatekey = "---";
    $resp = recaptcha_check_answer ($privatekey,
                                 $_SERVER["REMOTE_ADDR"],
                                 $_POST["recaptcha_challenge_field"],
                                 $_POST["recaptcha_response_field"]);
    if (!$resp->is_valid) {
    // What happens when the CAPTCHA was entered incorrectly
        header('Location: http://cpalander.net/dashboard.php?option=sendticket&error=captcha');
    } else {
        $subject = $_POST['subject'];
        $message = $_POST['message'];
        header('Location: http://cpalander.net/dashboard.php?option=sendticket&subject=' . urlencode($subject) . '&message=' . urlencode($message));
    }
    die();
 }
 else
 {
    require_once('recaptchalib.php');
    $privatekey = "---";
    $resp = recaptcha_check_answer ($privatekey,
                                 $_SERVER["REMOTE_ADDR"],
                                 $_POST["recaptcha_challenge_field"],
                                 $_POST["recaptcha_response_field"]);
    if (!$resp->is_valid) {
    // What happens when the CAPTCHA was entered incorrectly
        header('Location: http://cpalander.net/register.php?option=captcha');
    } else {
        $_SESSION['user2'] = $_POST['username'];
        $_SESSION['pass2'] = $_POST['password'];
        $_SESSION['mail2'] = $_POST['email'];
        header('Location: http://cpalander.net/makeacc.php');
    }
    die();
 }
 ?>

これは、ユーザーが存在するかどうかを確認し、エラーが発生した場合にユーザーをリダイレクトするコードの一部です。

<?php session_start();

 $data = $_GET["option"];
 $user = $_SESSION['user3'];
 $pass = $_SESSION['pass3'];

 function generateRandomString($length = 10) 
                    {
                        $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
                        $randomString = '';
                        for ($i = 0; $i < $length; $i++) {
                            $randomString .= $characters[rand(0, strlen($characters) - 1)];
                        }
                        return $randomString;
                    }
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>....</head>...

<body>...    

...<?php
                if ($data == 'checkuser')
                {
                        $user = $_SESSION['user3'];
                        $link = new mysqli('127.0.0.1', '*******', '*******', '*******');
                        if ($link->connect_errno) {
        die('Failed to connect to MySQL: (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
     }                  
                        $result = $link->query("SELECT * FROM users WHERE username='$user' AND active=1 AND banned=0");
                        $numrows = $result->num_rows;
                        if($numrows == 0)
                        {
                            $link->close();
                            session_destroy();
                            echo '<META HTTP-EQUIV="Refresh" Content="0; URL=login.php?option=notfound&user=' . $user . '">'; // This is the part that I used to check if the $user variable is set
                            exit;   
                        }
                        $row = $result->fetch_assoc();
                        $sid = $row['salt'];
                        $pass_h = hash('sha256', $sid . $pass);
                        $result = $link->query("SELECT * FROM users WHERE username='$user' AND password='$pass_h' AND active=1 AND banned=0");
                        $numrows = $result->num_rows;
                        if($numrows == 0)
                        {
                            $link->close();
                            session_destroy();
                            echo '<META HTTP-EQUIV="Refresh" Content="0; URL=login.php?option=notfound">';
                            exit;   
                        }
                        else
                        {
                            $link->close();
                            $_SESSION['user'] = $user;
                            echo '<META HTTP-EQUIV="Refresh" Content="0; URL=dashboard.php?option=home&user=' . $user . '">';
                            exit;
                        }
                        $link->close();
                }...</body>

誰かがこれについて私を助けることができますか? また、session_start(); ログインページコードの上にあります。

4

3 に答える 3

0

この投稿の日付を見ると、パーティーに遅れていることがわかりますが、非常によく似た問題を抱えていたため、これを見つけました. nocache=1 機能をレプリケートする PHP コードの私の投稿を参照してください。

問題を絞り込むための実験を次に示します。ページから離れてブラウザの Cookie に移動し、そのドメインの Cookie を削除します。ログイン ページに戻って、PHPSESSID Cookie があるかどうかを確認します。私の推測ではありません。次に、ログインを試みます (失敗すると言います)。次に、Cookie を再度確認します。PHPSESSID が表示されます。その後、次のログイン試行が機能します。

今すぐこれを試してください: そのドメインの Cookie をもう一度クリアしてから?nocache=1、URL の末尾にあるログイン ページを参照します。今回はおそらく PHPSESSID Cookie があり、今回は最初の試行でログインが機能します。

私の場合、?nocache=1それは機能しますが、同じコードをローカルホストでローカルに実行している場合でも必要ありません。

サーバー上のセッション処理設定のようです。

于 2015-09-02T05:05:43.750 に答える
0

session_start$_SESSION変数へのアクセスが必要なすべてのファイルに存在する必要があります。つまり、無関係なファイルにアクセスしている場合は、session_id() or session_start();それらに追加する必要があります(同じファイルへのrequire / includeが同じリクエストで行われた場合にsession_id() or session_start();、警告が表示されないようにする必要があります)Session already started

session_destroy()anew が再度呼び出されたときにセッションが再作成されるsession_unset()ため、代わりにセッションを破棄することをお勧めします。しかし、本当にセッションを破棄してやり直したい場合は、ブラウザをまたがる方法として、と(IE)の両方を呼び出します。session_destroy()session_start()session_unset()session_destroy()

また、質問自体とは別に、生$_POSTデータをチェックせずに URL に渡すことで、コードに XSS 脆弱性を許していることに注意する必要があります。

于 2013-05-05T21:30:53.650 に答える