1

私は一般的に私のために働くログインスクリプトを持っていますが、ログインのために保存されたクッキーをチェックした後、リダイレクト時に無限ループに入ることがあります。ブラウザは次のようなレポートを表示します:「Firefoxは、サーバーがこのアドレスの要求を決して完了しない方法でリダイレクトしていることを検出しました。」他の人もこの問題を報告しています。以下は、ログインプロセスの重要な要素です。このプロセス/スクリプトの問題が誰かにわかるのではないかと思います。

ありがとう、

ニック

まず、保護されている各ページの上部にあります。

<?php
session_start();

$_SESSION['url'] = $_SERVER['REQUEST_URI'];

require('login/config.php');
require('login/functions.php'); 

if (allow_access(Users) != "yes")
{ 
include ('login/check_login.php'); 
exit;
}
?>

次に、check_login.phpで:

<?
session_start();

//check to see if the user already has an open session
if (($_SESSION[user_name] != "") && ($_SESSION[password] != ""))
{

    header("Location:$_SESSION[redirect]");
    exit;
}

$lr_user = $_COOKIE['lr_user'];
$lr_pass = $_COOKIE['lr_pass'];

//check to see if cookies have been set previously
if(($lr_user != "") && ($lr_pass != ""))
{
    header("Location:/login/redirect.php");
    exit;
}

//if neither is true, redirect to login
    header("Location:/login/login.php");

?>

次に、redirect.phpで:

<?
session_start();

//require the functions file
require ("config.php");
require ("functions.php");

$lr_user = $_COOKIE['lr_user'];
$lr_pass = $_COOKIE['lr_pass'];

//check to see if cookies are already set, remember me
if ((!$lr_user) || (!$lr_pass))
{

$username = $_POST[username];
$password = $_POST[password];

}else{

$username = $lr_user;
$password = $lr_pass;

}

//sets cookies to remember this computer if the user asks to
if ($_POST[remember] == "Yes")
{
setcookie("lr_user", $username, $duration, "/", $domain);
setcookie("lr_pass", $password, $duration, "/", $domain);
}

//sets session variables
sess_vars($base_dir, $server, $dbusername, $dbpassword, $db_name, $table_name, $username, $password);

if(isset($_SESSION['url']))
  $_SESSION[redirect] = $_SESSION['url']; // holds url for last page visited.
else 
   $_SESSION[redirect] = "/index.php"; // default page for

//redirects the user    
header("Location:$_SESSION[redirect]");
?>

関数.php

<?php

//function to get the date
function last_login()
{
    $date = gmdate("Y-m-d");
    return $date;
}

//function that sets the session variable
function sess_vars($base_dir, $server, $dbusername, $dbpassword, $db_name, $table_name, $username, $password)
{

    //make connection to dbase
    $connection = @mysql_connect($server, $dbusername, $dbpassword)
                or die(mysql_error());

    $db = @mysql_select_db($db_name,$connection)
                or die(mysql_error());

    $sql = "SELECT * FROM $table_name WHERE username = '$username' and password = password('$password')";

    $result = @mysql_query($sql, $connection) or die(mysql_error());


    //get the number of rows in the result set
    $num = mysql_num_rows($result);

    //set session variables if there is a match
    if ($num != 0) 
    {
        while ($sql = mysql_fetch_object($result)) 
        {
            $_SESSION[first_name]   = $sql -> firstname;
            $_SESSION[last_name]    = $sql -> lastname; 
            $_SESSION[user_name]    = $sql -> username;       
            $_SESSION[password]     = $sql -> password;
            $_SESSION[group1]       = $sql -> group1;
            $_SESSION[group2]       = $sql -> group2;
            $_SESSION[group3]       = $sql -> group3;
            $_SESSION[pchange]      = $sql -> pchange;  
            $_SESSION[email]        = $sql -> email;
            $_SESSION[redirect]     = $sql -> redirect;
            $_SESSION[verified]     = $sql -> verified;
            $_SESSION[last_login]   = $sql -> last_login;
        }
    }else{
        $_SESSION[redirect] = "$base_dir/errorlogin.php";
    }
}


//functions that will determine if access is allowed
function allow_access($group)
{
    if ($_SESSION[group1] == "$group" || $_SESSION[group2] == "$group" || $_SESSION[group3] == "$group" ||
        $_SESSION[group1] == "Administrators" || $_SESSION[group2] == "Administrators" || $_SESSION[group3] == "Administrators" ||
        $_SESSION[user_name] == "$group")
        {
            $allowed = "yes";
        }else{
            $allowed = "no";
        }
    return $allowed;
}

//function to check the length of the requested password
function password_check($min_pass, $max_pass, $pass)
{

    $valid = "yes";
    if ($min_pass > strlen($pass) || $max_pass < strlen($pass))
    {
        $valid = "no";
    }

    return $valid;
}

?>

config.php

<?

//set up the names of the database and table
$db_name ="";
$table_name ="authorize";

//connect to the server and select the database
$server = "localhost";
$dbusername = "";
$dbpassword = "*";

//domain information
$domain = "";

//Change to "0" to turn off the login log
$log_login = "1";

//base_dir is the location of the files, ie http://www.yourdomain/login
$base_dir = "";

//length of time the cookie is good for - 7 is the days and 24 is the hours
//if you would like the time to be short, say 1 hour, change to 60*60*1
$duration = time()+60*60*24*365*10;

//the site administrator\'s email address
$adminemail = "";

//sets the time to EST
$zone=3600*00;

//do you want the verify the new user through email if the user registers themselves?
//yes = "0" :  no = "1"
$verify = "0";

//default redirect, this is the URL that all self-registered users will be redirected to
$default_url = "";

//minimum and maximum password lengths
$min_pass = 8;
$max_pass = 15;


$num_groups = 0+2;
$group_array = array("Users","Administrators");

?>
4

2 に答える 2

6

編集-これを試してください:

問題は、index.phpも含む「すべての」ページを保護しようとしていることだと思います。ただし、index.phpをページとして$_SESSION[redirect]変数に含めています。次のように考える必要があります。

  1. ユーザーがページにアクセスしようとしました
  2. 許可されているかどうかを確認する必要があります
  3. 許可されている場合は、中断することなくページを表示できるようにします
  4. それらがログインしていない(つまりログインしていない)場合-ログインページにリダイレクトします

スクリプトは、ページの表示が許可されている場合でも、それらをリダイレクトしようとしています(これがループの問題を引き起こしています)。

これは微妙な違いですが、重要な違いです(特に、すべてのページを保護しているため)。

私はこれを試してみます:

保護されたページの上部で、下部のスニペットを次のように変更します。

if (allow_access(Users) != "yes")
{ 
    include ('login/check_login.php'); 
    check_redirect();
}

check_login.phpでこれを試してください:

<?
session_start();

function check_redirect()
{

    //check to see if the user already has an open session
    if (($_SESSION[user_name] != "") && ($_SESSION[password] != ""))
    {
       // just return if they are a valid user (no need to redirect them)
       return;
    }

    $lr_user = $_COOKIE['lr_user'];
    $lr_pass = $_COOKIE['lr_pass'];

    //check to see if cookies have been set previously
    if(($lr_user != "") && ($lr_pass != ""))
    {
       // just return if they are a valid user (no need to redirect them)
       return;
    }

    //if neither is true, redirect to login
    header("Location:/login/login.php");
    die();

}  
?>

あなたのredirect.phpはあなたのページを保護するために必要ではありません、私はあなたがあなたの実際のlogin.phpスクリプトでこれを使うと仮定します、したがって:

$_SESSION['url']

彼らが到達しようとしていたページを保存していたはずであり、redirect.php / login.phpスクリプトは、ログインが成功した後、これを使用してリダイレクトする必要があります。

最後に、上記はテストされていないコードですが、あなたが持っていたものよりもうまくいくはずです、あなたがどのように乗り込むかを私に知らせてください。


正直なところ、configファイルやfunctionsファイル、関数など、不明な変数がまだいくつかあるため、コードの何が問題になっているのかを正確に判断するのは非常に困難です。

if (allow_access(Users) != "yes")

これは、ユーザーが「ユーザー」であると想定しています。同様に、この質問に対して大まかに入力された場合を除き、$ _ SESSION [user_name]のようなすべての変数は、アポストロフィを正しく追加する必要があります。そうしないと、至る所で通知が届きます。 (未定義の変数、想定される...など)これはセッションデータを台無しにする可能性があることは言うまでもありません。

おそらく、私があなたの現在のコードについてアドバイスを提供した場合、あなたはあなたのコードを修正することができるいくつかのことを試すことができるかもしれません。

複数のリダイレクト/スクリプト

最初にcheck_login.phpスクリプトとredirect.phpスクリプトを書き直します-2つの別々のスクリプト(組み合わせることができます)があるという事実は、本質的にリダイレクトにリダイレクトしているため、ある段階で常に問題を引き起こします(これはそうではありません)論理的にあなたがそれを大声で言うとき)。したがって、最初にスクリプトを1つの「auth.php」スクリプトに書き直します。また、認証が必要なページのインクルードを簡素化します。次に例を示します。

<?php
    session_start();

    // use require_once for your login scripts, not 'include' as you want an error to 
    // occur to halt the page processing if the file is not found, include will just
    // give a warning but still continue with the page processing (which you're trying
    // to protect). Lastly '_once' so you don't get multiple inclusions of the same
    // script by accident (which is always import for login / redirect scripts). 
    require_once('login/auth.php');

    // just create one function which will proxy all the other functions / includes
    // you could exclude this function and just use the require_once file for direct 
    // access - but I would say including a function will make it easier to understand.
    check_login();
?>

今auth.phpファイル:

<?php
    session_start();

    // if these are required use the _once. I would guess some of these 'functions'
    // may be able to be included within this 'auth.php' file directly?
    require_once('login/config.php');
    require_once('login/functions.php'); 

    // set your variables here
    $_SESSION['url'] = $_SERVER['REQUEST_URI'];

    // the main check login function
    function check_login() 
    {

        // Check if your user is logged in / needs to be logged in
        // perhaps something from your allow_access() function?

        // Do all the checks for session / cookie you should resolve the checks to
        // a simple bool variable (i.e. if the user is valid or not)
        $userIsValid = true || false; // get this from above code

        // Then use the redirect function and pass in the $userIsValid variable
        // which will tell the redirect() function where to redirect to.
        redirect($userIsValid);

    }

    // use a separate function for the redirect to keep it cleaner 
    // not too sure on all the Url's you have floating around in your code as I
    // would think you either want to let them to proceed to the page they were
    // trying to view (if validated) or you want them to login?      
    function redirect($validUser = false)
    {
        // if the user is valid, just return as you don't have to redirect them
        if ( $validUser ) {
            return true;
        }
        // otherwise just redirect them to the login page
        header("Location:/login/login.php");
        die();
    }

?>

安全

セッションに実際のパスワードを保存する必要はありません(保存するべきではありません!)。Cookieに対してもアドバイスします。ただし、パスワード/ユーザー名をCookieに保存する必要がある場合は、少なくともmd5()とソルトなどを使用して暗号化する必要があります。つまり、$ _SESSION['user_name']と$_SESSION['をチェックするのではなく、簡単に言うとパスワード']次のようになります。

// if the user has no valid session do something:
if ( !isset($_SESSION['id']) ) {


}

関心事の分離

なぜあなたが持っているのかわかりません:

$username = $_POST[username];
$password = $_POST[password];

redirect.phpファイル内で、ユーザーがログインするときにもこのスクリプトを使用していますか?あなたがそうなら、それは良い考えではないと思います(これは問題かもしれません)。すべての実際のログイン機能(ログイン後のリダイレクトを含む)を処理するための個別のスクリプトが必要です。上記は、a)ユーザーが有効であるかログインしているかどうかを確認するb)そうでない場合はリダイレクトする-基本的にWebページを保護することのみに関係する必要があります。

あなたのコード:

//check to see if the user already has an open session
if (($_SESSION[user_name] != "") && ($_SESSION[password] != ""))
{

    header("Location:$_SESSION[redirect]");
    exit;
}

彼らが有効なセッションを持っている場合、あなたは基本的にそれらをリダイレクトするので、私は文脈でこのビットを取得するかどうかわかりませんか?物事が少し逆行しているため(特にredirect.phpスクリプトと組み合わせた場合)、check_login.phpスクリプト全体を実際には理解していないことをスクラッチします。同じ変数をもう一度チェックしています($ lr_user)|| (!$ lr_pass)リダイレクトスクリプトで、check_login.phpスクリプトで設定されていないものへの参照を作成します。

編集:解決策になる可能性がありますか? 上記のコードブロックが$_SESSION['redirect']を参照しているものを見落とした場合を除き、それは$ _SESSION ['url']であるか、単にリダイレクトしないでください。$ _SESSION ['redirect']は、redirect.phpスクリプト(セッションが存在する場合は呼び出されない可能性があります)まで設定されません。

最終的な考え:

これがあなたの質問に本当に答えない場合は申し訳ありませんが、これはスクリプトをよく見て、それらをクリーン/単純化する良い機会になると思います。理想的には、これをOOPアプローチで確認する必要があります。つまり、セッションの作成、リダイレクト、ログインクラスです。ただし、単純な関数(手続き型)に固執する場合は、スクリプトごとに明確な分離を作成するようにしてください。つまり、一言で言えば:

  • 繰り返しないでください。たとえば、$ _SESSION['redirect']と$_SESSION['url']の両方が同じ値であるのはなぜですか?
  • リダイレクトにリダイレクトしないでください(1つのスクリプトでこれを処理する必要があります)
  • 懸念事項を分離する-ログインプロセスを実行するログインスクリプトと、実際のページを保護する認証/ aclスクリプトを用意します(2つを組み合わせないでください)。

上記が理にかなっていることを願っていますが、そうでない場合はお知らせください。

于 2012-06-07T00:29:14.107 に答える
0

あなたが本当にこのコードを使いたいのなら、私はここに答えがあると思います:

Cookieを無効にしたユーザー(プライベートブラウジング)の場合、check_login.phpの行が原因で、すべてのユーザーがスタックします。これらの値は設定されず、check_login.php- > login.php- > check_login.phpのループに分類されるためです。

$lr_user = $_COOKIE['lr_user']; 
$lr_pass = $_COOKIE['lr_pass']; 

//check to see if cookies have been set previously 
if(($lr_user != "") && ($lr_pass != "")) 
{     
header("Location:/login/redirect.php");     
exit; 
}

//if neither is true, redirect to login        
header("Location:/login/login.php"); 

Burすぐに利用できるセッション管理スニペットを使用することを強くお勧めします。

簡単に見てみると、次のような問題が発生します。

a)スティーブが言うように、ユーザー名とパスワードをCookieに保存してはいけません。ランダムなセッションID値のみを保存します。

setcookie("lr_user", $username, $duration, "/", $domain); 
setcookie("lr_pass", $password, $duration, "/", $domain); 

b)functions.phpSQLインジェクションの対象です。

$sql = "SELECT * FROM $table_name WHERE username = '$username' and 
password = password('$password')";

c)ユーザー入力がエスケープされることはありません。

$username = $_POST[username];                 
$password = $_POST[password]; 

d)セッション管理チェックをコード全体に分割しました。

于 2012-06-07T09:56:54.917 に答える