Бесконечный цикл при переадресации входа

У меня есть сценарий входа, который обычно работает для меня, но время от времени переходит в бесконечный цикл перенаправления после проверки файла cookie, хранящегося для входа. Браузер сообщит следующее: «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]"); ?> 

functions.php

 <?php //function to get the date function last_login() { $date = gmdate("Ymd"); 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"); ?> 

Solutions Collecting From Web of "Бесконечный цикл при переадресации входа"

EDIT – попробуйте следующее:

Я думаю, проблема в том, что я предполагаю, что вы пытаетесь защитить все страницы, которые также включают 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 не нужен для soley защиты ваших страниц, я предполагаю, что вы используете это с вашим фактическим скриптом login.php, поэтому:

 $_SESSION['url'] 

Сохранили бы страницу, к которой они пытались добраться, и ваш скрипт redirect.php / login.php должен просто использовать это, чтобы перенаправить их туда после успешного входа в систему.

Наконец, выше непроверенный код, но должен работать лучше, чем у вас, дайте мне знать, как вы это делаете.


Честно говоря, довольно сложно точно определить, что не так с вашим кодом, потому что есть еще несколько неизвестных переменных, таких как файлы конфигурации и функций и функция:

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

Я предполагаю, что пользователи должны быть «Пользователями», так же, если только для этого вопроса просто не было напечатано все переменные, которые у вас есть $ _SESSION [имя_пользователя], вы ДОЛЖНЫ убедиться, что вы правильно добавили апострофы, или вы получите уведомления по всему месту (неопределенная переменная, предполагаемая … и т. д.) не слишком упоминает, что это может испортить ваши данные сеанса.

Возможно, если бы я предложил некоторые советы по вашему текущему коду, вы можете попробовать некоторые вещи, которые могли бы исправить ваш код.

Несколько переадресаций / скриптов

Я бы сначала переписал ваши скрипты check_login.php и redirect.php – тот факт, что у вас есть два отдельных скрипта (которые можно объединить), всегда будет давать вам проблемы на определенном этапе, потому что по существу вы перенаправляетесь на перенаправление (что не логично, когда вы говорите это громко). Поэтому сначала перепишите свои сценарии на один скрипт 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 (ie 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 [' password '] это может быть что-то вроде:

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

Разделение проблем

Я не уверен, почему у вас есть:

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

В вашем файле redirect.php вы также используете этот скрипт для входа в систему? Я не думаю, что это хорошая идея, если вы (что может быть проблемой). У вас должен быть отдельный скрипт для обработки всех фактических функций входа в систему (включая перенаправление после входа в систему). Вышеизложенное должно быть связано только с: a) проверкой того, действительно ли пользователь зарегистрирован в журнале b) перенаправляет их, если нет – существенно защищает ваши веб-страницы.

Ваш код:

 //check to see if the user already has an open session if (($_SESSION[user_name] != "") && ($_SESSION[password] != "")) { header("Location:$_SESSION[redirect]"); exit; } 

Я не уверен, что получаю этот бит в контексте, поскольку вы в основном перенаправляете их, если у них есть действующий сеанс? Поцарапайте, что я действительно не понимаю весь скрипт check_login.php, так как все немного назад (особенно в сочетании с вашим скриптом redirect.php). Вы снова проверяете одни и те же переменные ($ lr_user) || (! $ lr_pass) в вашем скрипте перенаправления и ссылаясь на вещи, которые даже не были установлены в вашем скрипте check_login.php.

EDIT: Может быть решение? Если я не посмотрел что-то выше, этот блок кода ссылается на $ _SESSION ['redirect'], я думаю, что это должно быть либо $ _SESSION ['url'], либо просто не перенаправлять их. $ _SESSION ['redirect'] не устанавливается до скрипта redirect.php (который не может быть вызван, если сеанс существует).

Последние мысли:

Извините, если это на самом деле не отвечает на ваш вопрос, как вам бы хотелось, но я действительно думаю, что это будет хорошей возможностью хорошо взглянуть на ваш сценарий (ы) и очистить / упростить их. В идеале вы должны посмотреть на это с помощью подхода ООП, т. Е. Создать сеанс, перенаправить, класс входа. Но если вы придерживаетесь простых функций (процедурных), убедитесь, что вы создаете чистое разделение для каждого скрипта. Итак, в двух словах:

  • Не повторяйте себя, например, почему оба $ _SESSION ['redirect'] и $ _SESSION ['url'] – это одно и то же значение?
  • Не перенаправляйте на перенаправление (один скрипт должен справиться с этим)
  • Разделите свои проблемы. Имейте сценарий входа в систему, который выполняет процесс входа в систему, и сценарий аутентификации / acl, обеспечивающий безопасность ваших фактических страниц (не комбинируйте их).

Надежда выше имеет смысл, но дайте мне знать, если нет.

Если вы действительно хотите пойти с этим кодом, я думаю, что вот ответ:

Для пользователей, у которых отключены куки (частный просмотр), все ваши пользователи будут застревать из-за строк в 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 КОГДА-ЛИБО. Вы сохраняете только случайное значение идентификатора сеанса.

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

b) Ваши функции.php подвержены SQL-инъекции .

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

c) Пользовательские входы никогда не экранируются.

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

d) Вы разделили свои проверки управления сеансом по всему коду.