Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: И опять вопрос об авторизации или как правильно logout оформить
 
 автор: Geo_Li   (06.09.2007 в 11:05)   письмо автору
 
 

Написал код, как будто рабочий. Но никак не мог реализовать logout. Придумал вариант, ссылка на сайт регистрации но с случайным числом $log. Если ее нет, то идет регистрация, если есть, выход из регистрации. Знаю, возможно не очень красиво, но по авторицации можно найти информацию, а вот по выходу из авторизаци как то нет.
Хотелось бы, чтобы знатоки посоветовали новичку, какие есть недочеты с крипте. А так же вопрос. После выхода из авторизации никак не удается тут же войти по новой. Закрыл броузер, открыл по новой, авторизация идет. А сразу после выхода зайти по новой невозможно. В чем может быть проблема.
Ниже код авторизации, а еще ниже самой формы.
Буду непомерно благодарен за советы.


 $IN_LOG['log']= false;
 $IN_LOG['id']= "";

if (isset($_GET['log'])){
 setcookie('_name');
 setcookie('_pass');
 flush();
 header ('Location: index.php');
}



 if (isset($_COOKIE['_name']) and isset($_COOKIE['_pass']))
                 {
 $username = preg_replace("/[^a-z0-9]/i", "", $_COOKIE['_name']);
 $password = preg_replace("/[^a-z0-9]/i", "", $_COOKIE['_pass']);

 $sql = "SELECT  * FROM kar_n_user WHERE login = '" . str_replace("\'", "''", $username) . "'";
 $result = mysql_query ($sql);

 while ($myro = mysql_fetch_array($result)){

    if( $password == $myro['pass'])
                      {
                       $IN_LOG['log']= true;
                       $IN_LOG['id']= $myro['user_id'];
                       }else{
                       $IN_LOG['log']= false;
                       $IN_LOG['id']= "";
                      }
      }
 }elseif( isset($_POST['name']))
 {
 $username = preg_replace("/[^a-z0-9]/i", "", $_POST['name']);
 $password = preg_replace("/[^a-z0-9]/i", "", $_POST['pass']);

 $sql = "SELECT * FROM kar_n_user WHERE login = '" . str_replace("\'", "''", $username) . "'";
 $result = mysql_query ($sql);

 while ($myro = mysql_fetch_array($result)){

    if( md5($password) == $myro['pass'] )
                      {
                       setcookie('_name', $username, (time() + 31536000));
                       setcookie('_pass', md5($password), (time() + 31536000));
                       $IN_LOG['log']= true;
                       $IN_LOG['id']= $myro['user_id'];
                       }else{
                       $IN_LOG['log']= false;
                       $IN_LOG['id']= "";
                      }
            }
 }



Сама форма авторизации. Если авторизация нормальная, то $IN_LOG['log']=true и мы видем ссылку для выхода. Если нет, то форма для авторизации.

if ($IN_LOG['log']) {

echo "<a href='$PHP_SELF?log=".time()."'>Выход</a>";
}else{
echo "<form name='FormName' action='$PHP_SELF' method='post'>
<input name='name' type='text'>
<input name='pass' type='password'>
<input type='submit' value='Войти'>
</form>";
}



Заранее спасибо за подсказки и критику. Но не пинайте ногами новичка.

   
 
 автор: Trianon   (06.09.2007 в 11:31)   письмо автору
 
   для: Geo_Li   (06.09.2007 в 11:05)
 

Объясните, пожалуйста, зачем в двух местах это: str_replace("\'", "''", ?
И зачем вот это: $password = preg_replace("/[^a-z0-9]/i", "", $_POST['pass']); ?
Кроме того, я бы очень не советовал укладывать пароль куда-либо . В том числе и в кукис.
Не надо брать пример с лайтфорума в этом аспекте.

Кстати, Вы пытаетесь в одной из точек класть хеш. А в другой - сам пароль. Определились бы чтоли... И тогда уж совет: хеш, хранящийся в базе, тоже не стоит напрямую класть в кукис. Лучше прохешировать пароль дважды. Еще лучше - с разным инит-вектором (salt)

Касательно выхода из авторизации - это всего лишь вытирание кукиса с аутентифицирующим элементом.
- в Вашем случае :
setcookie('_pass', '', (time() - 24*3600));

   
 
 автор: Geo_Li   (06.09.2007 в 12:13)   письмо автору
 
   для: Trianon   (06.09.2007 в 11:31)
 

Спасибо за Ваши замечания и подсказки.
Как вы понимаете, новичек, он и в африке новичек.
Зачем str_replace("\'", "''" и $password = preg_replace("/[^a-z0-9]/i", "", $_POST['pass']); ? Начитавшись об уязвимостях скриптов и увидев такие варианты, как сорока неприминул притащить в скрипт, для придания весомости и перестрахованности. Должен признать, после трезвого осмотра, глупо и лишне.

По поводу укладывания пароля в куки. На многих сайтах, к примеру как и этот, после регистрации и авторизации, авторизация хранится определенное время. т.е. спустя к примеру неделю, зайдя сюда, мне не нужно авторизовать себя по новой. Не знаю как это реализовано, вот и пошел таким путем, загоняя пароль и имя пользователя в куки. Может подскажите, каким путем можно реализовать это. (т.е. не авторизоваться по новой).

Кстати, Вы пытаетесь в одной из точек класть хеш. А в другой - сам пароль.

Не отрицаю, возможно, но не нашел где. Вообще setcookie с паролем проходит дважды, первый раз я пытался вытереть данные из кукисов используя setcookie('_pass'), теперь вижу, нужно было использовать setcookie('_pass', '', (time() - 24*3600)) спасибо за подсказку.

Лучше прохешировать пароль дважды. Еще лучше - с разным инит-вектором (salt)
Двойное хиширование касается пароля, который ложится в куки?

И еще вопрос, как происходит востановление пароля. т.е. Когда пользователь забыл пароль, он идет на страничку, указывает свой электронный адрес, происходит проверка в базе, есть ли такой пользователь и если есть ему отправляется его логин и пароль. Но пароль хешировался, как его востанавливают. Или для этих целей есть еще одна таблица, где не хешированые пароли?

   
 
 автор: Trianon   (06.09.2007 в 12:44)   письмо автору
 
   для: Geo_Li   (06.09.2007 в 12:13)
 

>Должен признать, после трезвого осмотра, глупо и лишне.

Посмотрите в сторону mysql_escape_string() .
Еще очень советую поглядеть задачу 21 (http://softtime.ru/forum/read.php?id_forum=7&id_theme=37909 и рядом)

в самом начале, строки
$password = preg_replace("/[^a-z0-9]/i", "", $_COOKIE['_pass']);
$password = preg_replace("/[^a-z0-9]/i", "", $_POST['pass']);
дают понять что в кукисе пароль открытый.

>Кстати, Вы пытаетесь в одной из точек класть хеш. А в другой - сам пароль.
>Не отрицаю, возможно, но не нашел где.

в самом конце строка
setcookie('_pass', md5($password), (time() + 31536000));
явно говорит, что в кукисе хеш.


>И еще вопрос, как происходит востановление пароля.

Пароль не восстанавливают.
Его генерируют заново случайным образом. Одноразовый пароль.
При первом же входе пользователя заставляют сменить одноразовый пароль на постоянный.
При этом делают запрет на одновременную (в течение карантинного интервала) смену пароля и е-мэйла.
Иногда, правда, некоторыми пунктами пренебрегают.

А если Вы на портале обнаружили систему восстановления Вашего старого пароля - это намек. Адекватно работать с чужими приватными данными на таком портале не умеют (или , что еще хуже - не желают). Соответственно, либо Вы уходите с портала, либо если он Вам ценен, делаете пароль таким, чтоб он мало отличался от криптохеша.
В таком разе вероятность скомпрометировать другие ресурсы при атаке на данный - снижается до минимума.

>Или для этих целей есть еще одна таблица, где не хешированые пароли?
Ни в коем случае.
А вот хранить криптохеши (и прочие конфиденциальные данные, вроде скрытых е-мэйлов) в отдельной таблице - вполне разумно.

   
 
 автор: Ralph   (06.09.2007 в 13:41)   письмо автору
 
   для: Trianon   (06.09.2007 в 12:44)
 

Заставили меня призадуматься :) я сейчас храню в aes-en/decrypt,но... неужели это так опасно ? Пусть даже узнают криптослово,узнать чистые пароли можно,лишь получив доступ к бд,а когда я получу доступ,мне уже пофиг,обратимое шифрование или нет.И еще,пожалуйста поподробнее о смысле хранения хэшей/е-майлов в отдельной таблице ?

   
 
 автор: Geo_Li   (06.09.2007 в 14:06)   письмо автору
 
   для: Ralph   (06.09.2007 в 13:41)
 

>>Кстати, Вы пытаетесь в одной из точек класть хеш. А в другой - сам пароль.

>в самом конце строка
>setcookie('_pass', md5($password), (time() + 31536000));
>явно говорит, что в кукисе хеш.

Немного не понял. Имя переменной '_pass' говорит?
или md5($password) не будет выполняться в данном случае?

Планировалось здесь ложить хеш, а где я ложу пароль?

*прошу просить за надоедливость и непонятливость...

PS. А про отдельную таблицу и правда, можно поподробней...

   
 
 автор: Geo_Li   (07.09.2007 в 15:09)   письмо автору
 
   для: Geo_Li   (06.09.2007 в 14:06)
 

Внес изменения в код, надеюсь правильно понял написанное Вами. Разнес данные по двум таблицам, в одной хранятся основные данные пользователя, во второй только информация о соединении, т.е. логин, случайное число для идентификации логина и время обновления информации. Жду критики


$IN_LOG['log']= false;
$IN_LOG['id']= "";

//запускаем генератор случайного числа для описания 
mt_srand(time()+(double) microtime()*1000000);

//если пользователь логится впервые, то проходим этим путем, проверяя его данные 
//с основной таблицей и если все в порядке заносим в куки его логин время и случайное число
if (isset($_POST['name']) and  $_POST['pass'])
          {
   $username = mysql_escape_string($_POST['name']);
   $password = $_POST['pass'];

   $result=mysql_query("SELECT * FROM kar_n_user WHERE login = '".$username."' LIMIT 1");

   if($myro = mysql_fetch_array($result))
       {
       if( md5($password) == $myro['pass'] )
                      {
                      $sd=md5(rand());
                      $data=date('Y-m-d H:i');
                      setcookie('nm', $username, (time() + 30*24*3600));
                      setcookie('sd', $sd, (time() + 30*24*3600));
                      $IN_LOG['log']= true;
                      $IN_LOG['id']= $myro['user_id'];
                      $result=mysql_query("SELECT * FROM user_list WHERE name='".$username."' LIMIT 1");
//проверяется, логился ли пользователь раньше, если да, то его запись обновляется, 
//если нет, добавляется.
                      if($myro = mysql_fetch_array($result))
                          {
 mysql_query("UPDATE user_list SET sd='".$sd."', data='".$data."' WHERE id='".$myro['id']."'");
  }else{
  mysql_query("INSERT INTO user_list SET name='".$username."', sd='".$sd."', data='".$data."'");
  }
                       }else{
                      $IN_LOG['log']= false;
                      $IN_LOG['id']= "";
                      }
            }

//если есть данные в куках, то берем их от туда и проверяем 
}elseif (isset($_COOKIE['nm']) and isset($_COOKIE['sd']))
                 {
 $username = mysql_escape_string($_COOKIE['nm']);
 $password = $_COOKIE['sd'];
 $result=mysql_query("SELECT * FROM user_list WHERE name='".$username."' LIMIT 1");
//если он логился раньше, то генерируем новое случайное число, пересохраняем его в куки 
//и обнавляем данные в таблице 
if($myro = mysql_fetch_array($result))
                 {
                  if( $password == $myro['sd'])
                      {
                      $sd=md5(rand());

                      setcookie('nm', $username, (time() + 30*24*3600));
                      setcookie('sd', $sd, (time() + 30*24*3600));

                      mysql_query("UPDATE 'user_list' SET sd='".$sd."', data='".date("Y-m-d H:i")."' WHERE id='".$myro['id']."'");
                      $IN_LOG['log']= true;
                      $result=mysql_query("SELECT * FROM kar_n_user WHERE login = '".$username."' LIMIT 1");
                      if($myro = mysql_fetch_array($result))  $IN_LOG['id']= $myro['user_id'];
                       }else{
                      $IN_LOG['log']= false;
                      $IN_LOG['id']= "";
                      }
      }

}


Logout делается таким образом.

setcookie('nm', '', (time() - 24*3600));
 setcookie('sd', '', (time() - 24*3600));

 header ('Location: ../index.php');


По ходу вопросы. Не сильно ли опять намудрил. Есть ли серьезные ошибки. Не осложняет ли это работу скрипта, может проще проводить проверка один раз в начале, и если все ОК, запускать сесию и хранить там, что все было нормально и так до момента закрытия странички?

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования