Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > авторизация без регистрации


Автор: welt 4.1.2007, 15:33
приветсвую всех!
хочу переделать вот эту систему авторизации
http://vingrad.ru/PHP-ART-002849 
так чтобы не было регистрации. т.е. чтобы в бд хранился только один логин и пароль.короче вот что у меня получилось:
1)Сначала я создаю бд:
Код

<?
$user="auth";
$pass="1216376";
$dbname="auth";
$host="localhost";
mysql_connect($host,$user,$pass);
@mysql_select_db($dbname) or die("Unable to select database");

$query1="CREATE TABLE auth_members 
(id SMALLINT NOT NULL AUTO_INCREMENT ,
name TINYTEXT NOT NULL ,
password TINYTEXT NOT NULL ,
PRIMARY KEY (id))";

$query2="CREATE TABLE auth_sessions (
member SMALLINT NOT NULL ,
time INT(14) NOT NULL ,
hash TINYTEXT NOT NULL ,)";

mysql_query($query1);
mysql_query($query2);
mysql_close();

?>


2)Потом создаю запись в таблице:
Код

$query3 = "INSERT INTO auth_members VALUES ('1','serega','password')";
mysql_query($query3);


3)Далее я пишу сам код http://vingrad.ru/PHP-ART-002849 
(я закоментировал форму для регистрации и пропустил пункт 4. Регистрация)
Код

<?php
//Напишем функцию для создания хэша безопасности:
function hash( $user , $user_agent , $user_ip )
 {  return md5( $user ) . md5( $user_agent ) . md5( $user_ip );  }

?>
<?php
//Теперь для определения IP пользователя:
function get_ip()
 {
  if ($ip = getenv("HTTP_CLIENT_IP"))
   {  return $ip;  }

  if ($ip = getenv("HTTP_X_FORWARDED_FOR"))
   {
    if ($ip == '' || $ip == "unknown")
     {  $ip = getenv("REMOTE_ADDR");  }

    return $ip;
   }
  if ( $ip = getenv("REMOTE_ADDR") )
   {  return $ip;  }
 } 
?>

<?php
//Для определения текущего времени с точностью в миллисекундах:

function getmicrotime()
 {
  $mt = explode( " ", microtime() );
  return ( (float)$mt[0] + (float)$mt[1] );
 }

?>

<?php
/*
функция, которая будет делать редирект на этот же скрипт, с передачей параметра с возникшей ошибкой при регистрации или авторизации. Именно редирект нужен для того, чтобы очистить POST данные:
*/
function redirect( $par )
 {
  header( "Location: qwe.php?task=" . $par );
  exit;
 }

?>


<?php
/*
Теперь сделаем так, что в случае если пользователь авторизован, ему покажется сообщение «Welcome»и ссылка для выхода ( qwe.php?quit ), в противном случае форма ввода логина и пароля.
*/
if( isset( $_COOKIE['time'] ) && isset( $_COOKIE['name'] ) && check() == TRUE )
 {  print "Welcome.<br><a href='?quit'>Выйти</a>";  }
else
 {
  if( ! empty( $_GET['task'] ) )
   {
    switch( $_GET['task'] )
     {
      case "nepass":   print "Пароли не совпадают";
           break;
      case "not_auth": print "Логин или пароль неверный.";
           break;
      case "fields":   print "Не заполнены все поля";
           break;
      case "exists":   print "Пользователь с таким именем уже существует";
           break;
     }

    print "<br><br>";
   }

?>
Вход: <form action='' method='POST'>
Логин: <input type='text' name='name' maxlength='127' value=''><br>
Пароль: <input type='text' name='pass' maxlength='127' value=''><br>
<input type='Submit' name='blogin' value='Вход'><br>
</form>

<?php 
/*
Регистрация: <form action='' method='POST'>
Логин: <input type='text' name='name' maxlength='127' value=''><br>
Пароль: <input type='text' name='pass1' maxlength='127' value=''><br>
Повторите пароль: <input type='text' name='pass2' maxlength='127' value=''><br>
<input type='Submit' name='breg' value='Вход'>
</form>
*/
?>

<?php
 }

?>
<?php

//-------------Авторизация---------------------

if( $_SERVER['REQUEST_METHOD'] == "POST" && isset( $_POST['blogin'] ) )
 {
  if( empty( $_POST['name'] ) || empty( $_POST['pass'] ) )
   {  redirect( "fields" );  }

  auth();
 }

?>
<?php

function auth()
 {
  $result = mysql_query( "SELECT `*` FROM `auth_members` WHERE `name` = '" . mysql_escape_string( $_POST['name'] ) . "' AND `password` = '" . md5( $_POST['pass'] ) . "' LIMIT 1" );

  if( mysql_num_rows( $result ) == 0 )
   {  redirect( "not_auth" );  }

  $user = mysql_fetch_object( $result );

  $tm = getmicrotime();
  mysql_query( "INSERT INTO `auth_sessions` VALUES( " . $user -> id . " , " . time() . " , '" . hash( $user -> name , $_SERVER['HTTP_USER_AGENT'] , get_ip() , $tm ) . "' )" );

  setcookie( "time" , $tm , time() + 900 , "/" );
  setcookie( "name" , $user -> name , time() + 900 , "/" );

  redirect( "" );
 }

?>

<?php
/*Продление сессии, при каждом новом действии пользователя. */
function check()
 {
  $result = mysql_query( "SELECT `*` FROM `auth_members` WHERE `name` = '" . mysql_escape_string( $_COOKIE['name'] ) . "' LIMIT 1" );

  if( mysql_num_rows( $result ) == 0 )
   {  redirect( "not_auth" );  }

  $user = mysql_fetch_object( $result );

  $minutes = 15;
  $result = mysql_query( "SELECT `*` FROM `auth_sessions` WHERE `member` = " . $user -> id . " AND `hash` = '" . hash( $user -> name , $_SERVER['HTTP_USER_AGENT'] , get_ip() , $_COOKIE['time'] ) . "' AND `time` > " . ( time() - ( $minutes * 60 ) ) . " LIMIT 1 " );
  print mysql_error();

  if( mysql_num_rows( $result ) == 0 )
   {  redirect( "not_auth" );  }

  if( isset( $_GET['quit'] ) )
   {
    mysql_query( "DELETE FROM `auth_session` WHERE `id` = " . $user -> id . " AND `hash` = '" . hash( $user -> name , $_SERVER['HTTP_USER_AGENT'] , get_ip() , $_COOKIE['time'] ) . "'" );

    setcookie( "time" , "" , 900 , "/" );
    setcookie( "name" , "" , 900 , "/" );

    return FALSE;
   }
  else
   {
    mysql_query( "UPDATE `auth_session` SET `time` = " . time() . " WHERE `member` = " . $user -> id . " AND `hash` = '" . hash( $user -> name , $_SERVER['HTTP_USER_AGENT'] , get_ip() , $_COOKIE['time'] ) . "'" );

    setcookie( "time" , $_COOKIE['time'] , time() + ( $minutes * 60 ) , "/" );
    setcookie( "name" , $_COOKIE['id'] , time() + ( $minutes * 60 ) , "/" );

    return TRUE;
   }
 }

?>

<?php

/*
Дальше если пользователь выходит из авторизированной зоны (нажимает ссылку ?quit), то мы удаляем запись из таблицы сессий, ту, ища ее по ID пользователя и хэшу безопасности. После чего пишем в куки пустые значения и ставим время жизни далеко в прошлом. Затем выходим из функции и возвращаем FALSE, чтобы не выполнился код, описанный в третьей части статьи:
*/

if( isset( $_COOKIE['time'] ) && isset( $_COOKIE['name'] ) && check() == TRUE )
 {  print "Welcome.<br><a href='?quit'>Âûéòè</a>";  }

?>


Далее после ввода логина и пароля
у меня появляются ошибки:
Код

Warning: mysql_query(): Access denied for user 'ODBC'@'localhost' (using password: NO) in qwe.php on line 114

Warning: mysql_query(): A link to the server could not be established in qwe.php on line 114
Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in qwe.php on line 116
Warning: Cannot modify header information - headers already sent by (output started at qwe.php on line 43

Подскажите как исправить?????

Автор: Mal Hack 4.1.2007, 15:44
Ну зачем так статью уродовать.. Есть же прикрепленный файл...

Цитата(welt @  4.1.2007,  15:33 Найти цитируемый пост)
Подскажите как исправить????? 

К БД подсоединиться.. Черным по белому же написано.

Цитата(welt @  4.1.2007,  15:33 Найти цитируемый пост)
так чтобы не было регистрации. т.е. чтобы в бд хранился только один логин и пароль

А зачем тогда БД? Храни логи и хэш от пароля в файле.

Автор: welt 4.1.2007, 15:51
а разве я не подсоединился к бд???

Автор: Mal Hack 4.1.2007, 15:58
welt, а ты покажи где?

Автор: welt 4.1.2007, 16:12
в пункте  "1)Сначала я создаю бд..."
смотри в самом верху моего сообщения

Автор: Mal Hack 4.1.2007, 16:14
welt, и, дальше что? В скрипте авторизации где соединение с БД... Скрипт телепатически с другим связей не устанавливает.


Автор: GZep 4.1.2007, 16:21
Цитата(Mal Hack @  4.1.2007,  16:14 Найти цитируемый пост)
другим связей не устанавливает.

Да даже еслибы устанавливал, не помогло бы, потому что там в конце все-равно стоит:
Цитата(welt @  4.1.2007,  15:33 Найти цитируемый пост)
mysql_close();

 smile 

P.S. mysql_close() вообще ставить совсем необязательно, PHP и так всегда автоматически отключается от СУБД.

Автор: welt 4.1.2007, 16:29
хорошо
я добавил в самом начале этот код
Код

<?
$user="auth";
$pass="1216376";
$dbname="auth";
$host="localhost";
mysql_connect($host,$user,$pass);
@mysql_select_db($dbname) or die("Unable to select database");

$query1="CREATE TABLE auth_members 
(id SMALLINT NOT NULL AUTO_INCREMENT ,
name TINYTEXT NOT NULL ,
password TINYTEXT NOT NULL ,
PRIMARY KEY (id))";

$query2="CREATE TABLE auth_sessions (
member SMALLINT NOT NULL ,
time INT(14) NOT NULL ,
hash TINYTEXT NOT NULL )";

mysql_query($query1);
mysql_query($query2);
mysql_close();
?>

потом я сделал SQL-запрос через phpMyAdmin-т.е. добавил запись в таблицу auth_members 
Код

INSERT INTO `auth_members` ( `id` , `name` , `password` ) 
VALUES (
'1', 'serega', '1234567'
);

и дальше я ввожу пароль и логин и опять такие же ошибки.....что делать?

Добавлено @ 16:34 
да я убрал mysql_close();
протом запустил и вот такие ошибки:

Код

Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in qwe.php on line 147
Warning: Cannot modify header information - headers already sent by (output started at qwe.php:32) in qwe.php on line 74



вот строка 147:
if( mysql_num_rows( $result ) == 0 )

вот строка 74:
header( "Location: qwe.php?task=" . $par );

Как исправить?

Автор: Mal Hack 4.1.2007, 16:36
welt, у тебя ДВА РАЗНЫХ СКРИПТА. В ОДНОМ ЕСТЬ СОЕДИНЕНИЕ с БД в другом - НЕТ... Неужели непонятно, что соединение с БД надо открывать в том скрипте, где оно должно быть использовано????

Добавлено @ 16:37 
В начало скрипта error_reporting(E_ALL);
Это раз.
Два.
В скрипте сделай все единым,  а не разделяй каждую функцию через ?><?php

Автор: -=Ustas=- 4.1.2007, 16:39
Цитата(welt @  4.1.2007,  16:29 Найти цитируемый пост)
if( mysql_num_rows( $result ) == 0 )

Неверный SQL-запрос  выше.

Цитата(welt @  4.1.2007,  16:29 Найти цитируемый пост)
header( "Location: qwe.php?task=" . $par );

Это нужно посылать ДО любого вывода в поток.

Автор: welt 4.1.2007, 16:41
Mal Hack, 
у меня один скрипт!!!!!!
вот он:
Код

<?
$user="auth";
$pass="1216376";
$dbname="auth";
$host="localhost";
mysql_connect($host,$user,$pass);
@mysql_select_db($dbname) or die("Unable to select database");

$query1="CREATE TABLE auth_members 
(id SMALLINT NOT NULL AUTO_INCREMENT ,
name TINYTEXT NOT NULL ,
password TINYTEXT NOT NULL ,
PRIMARY KEY (id))";

$query2="CREATE TABLE auth_sessions (
member SMALLINT NOT NULL ,
time INT(14) NOT NULL ,
hash TINYTEXT NOT NULL )";

mysql_query($query1);
mysql_query($query2);
//mysql_close();

?>



<?php
//Напишем функцию для создания хэша безопасности:
function hash( $user , $user_agent , $user_ip )
 {  return md5( $user ) . md5( $user_agent ) . md5( $user_ip );  }

?>
<?php
//Теперь для определения IP пользователя:
function get_ip()
 {
  if ($ip = getenv("HTTP_CLIENT_IP"))
   {  return $ip;  }

  if ($ip = getenv("HTTP_X_FORWARDED_FOR"))
   {
    if ($ip == '' || $ip == "unknown")
     {  $ip = getenv("REMOTE_ADDR");  }

    return $ip;
   }
  if ( $ip = getenv("REMOTE_ADDR") )
   {  return $ip;  }
 } 
?>

<?php
//Для определения текущего времени с точностью в миллисекундах:

function getmicrotime()
 {
  $mt = explode( " ", microtime() );
  return ( (float)$mt[0] + (float)$mt[1] );
 }

?>

<?php
/*
функция, которая будет делать редирект на этот же скрипт, с передачей параметра с возникшей ошибкой при регистрации или авторизации. Именно редирект нужен для того, чтобы очистить POST данные:
*/
function redirect( $par )
 {
  header( "Location: qwe.php?task=" . $par );
  exit;
 }

?>


<?php
/*
Теперь сделаем так, что в случае если пользователь авторизован, ему покажется сообщение «Welcome»и ссылка для выхода ( qwe.php?quit ), в противном случае форма ввода логина и пароля.
*/
if( isset( $_COOKIE['time'] ) && isset( $_COOKIE['name'] ) && check() == TRUE )
 {  print "Welcome.<br><a href='?quit'>Выйти</a>";  }
else
 {
  if( ! empty( $_GET['task'] ) )
   {
    switch( $_GET['task'] )
     {
      case "nepass":   print "Пароли не совпадают";
           break;
      case "not_auth": print "Логин или пароль неверный.";
           break;
      case "fields":   print "Не заполнены все поля";
           break;
      case "exists":   print "Пользователь с таким именем уже существует";
           break;
     }

    print "<br><br>";
   }

?>
Вход: <form action='' method='POST'>
Логин: <input type='text' name='name' maxlength='127' value=''><br>
Пароль: <input type='text' name='pass' maxlength='127' value=''><br>
<input type='Submit' name='blogin' value='Вход'><br>
</form>

<?php 
/*
Регистрация: <form action='' method='POST'>
Логин: <input type='text' name='name' maxlength='127' value=''><br>
Пароль: <input type='text' name='pass1' maxlength='127' value=''><br>
Повторите пароль: <input type='text' name='pass2' maxlength='127' value=''><br>
<input type='Submit' name='breg' value='Вход'>
</form>
*/
?>

<?php
 }

?>
<?php

//-------------Авторизация---------------------

if( $_SERVER['REQUEST_METHOD'] == "POST" && isset( $_POST['blogin'] ) )
 {
  if( empty( $_POST['name'] ) || empty( $_POST['pass'] ) )
   {  redirect( "fields" );  }

  auth();
 }

?>
<?php

function auth()
 {
  $result = mysql_query( "SELECT `*` FROM `auth_members` WHERE `name` = '" . mysql_escape_string( $_POST['name'] ) . "' AND `password` = '" . md5( $_POST['pass'] ) . "' LIMIT 1" );

  if( mysql_num_rows( $result ) == 0 )
   {  redirect( "not_auth" );  }

  $user = mysql_fetch_object( $result );

  $tm = getmicrotime();
  mysql_query( "INSERT INTO `auth_sessions` VALUES( " . $user -> id . " , " . time() . " , '" . hash( $user -> name , $_SERVER['HTTP_USER_AGENT'] , get_ip() , $tm ) . "' )" );

  setcookie( "time" , $tm , time() + 900 , "/" );
  setcookie( "name" , $user -> name , time() + 900 , "/" );

  redirect( "" );
 }

?>

<?php
/*Продление сессии, при каждом новом действии пользователя. */
function check()
 {
  $result = mysql_query( "SELECT `*` FROM `auth_members` WHERE `name` = '" . mysql_escape_string( $_COOKIE['name'] ) . "' LIMIT 1" );

  if( mysql_num_rows( $result ) == 0 )
   {  redirect( "not_auth" );  }

  $user = mysql_fetch_object( $result );

  $minutes = 15;
  $result = mysql_query( "SELECT `*` FROM `auth_sessions` WHERE `member` = " . $user -> id . " AND `hash` = '" . hash( $user -> name , $_SERVER['HTTP_USER_AGENT'] , get_ip() , $_COOKIE['time'] ) . "' AND `time` > " . ( time() - ( $minutes * 60 ) ) . " LIMIT 1 " );
  print mysql_error();

  if( mysql_num_rows( $result ) == 0 )
   {  redirect( "not_auth" );  }

  if( isset( $_GET['quit'] ) )
   {
    mysql_query( "DELETE FROM `auth_session` WHERE `id` = " . $user -> id . " AND `hash` = '" . hash( $user -> name , $_SERVER['HTTP_USER_AGENT'] , get_ip() , $_COOKIE['time'] ) . "'" );

    setcookie( "time" , "" , 900 , "/" );
    setcookie( "name" , "" , 900 , "/" );

    return FALSE;
   }
  else
   {
    mysql_query( "UPDATE `auth_session` SET `time` = " . time() . " WHERE `member` = " . $user -> id . " AND `hash` = '" . hash( $user -> name , $_SERVER['HTTP_USER_AGENT'] , get_ip() , $_COOKIE['time'] ) . "'" );

    setcookie( "time" , $_COOKIE['time'] , time() + ( $minutes * 60 ) , "/" );
    setcookie( "name" , $_COOKIE['id'] , time() + ( $minutes * 60 ) , "/" );

    return TRUE;
   }
 }

?>

<?php

/*
Дальше если пользователь выходит из авторизированной зоны (нажимает ссылку ?quit), то мы удаляем запись из таблицы сессий, ту, ища ее по ID пользователя и хэшу безопасности. После чего пишем в куки пустые значения и ставим время жизни далеко в прошлом. Затем выходим из функции и возвращаем FALSE, чтобы не выполнился код, описанный в третьей части статьи:
*/

if( isset( $_COOKIE['time'] ) && isset( $_COOKIE['name'] ) && check() == TRUE )
 {  print "Welcome.<br><a href='?quit'>Âûéòè</a>";  }

?>


Как исправить ошибки?????

Добавлено @ 16:43 
-=Ustas=-, как это исправить?

Автор: Mal Hack 4.1.2007, 16:49
welt, 
Цитата(Mal Hack @  4.1.2007,  16:36 Найти цитируемый пост)
В начало скрипта error_reporting(E_ALL);
Это раз.
Два.
В скрипте сделай все единым,  а не разделяй каждую функцию через ?><?php 

Далее. Читаем вот это: http://ru2.php.net/global

Автор: GZep 4.1.2007, 17:00
попробуй в самом начале поставить (это исправит возможное обрушение редиректа)
Код

ob_start();

Далее вместо
Код

?>
<?php

просто ничего не ставь, не знаю, где ты такого понабрался, это бредом похнет...

P.S. не забывай писать текст ошибки, это не так трудно скопировать пару строк ошибку в форму ввода сообщения...

Автор: welt 4.1.2007, 17:11
GZep, 
я поставил ob_start(); в самом начале.
теперь я ввожу логин и пароль(ввожу ПРАВИЛЬНО)
и мне пишет что Логин или пароль неверный.

а если закоментировать строчку ob_start(); то будут такие ошибки:


Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in qwe.php on line 144
Warning: Cannot modify header information - headers already sent by (output started at qwe.php:110) in qwe.php on line 71

строка 144: if( mysql_num_rows( $result ) == 0 )
строка 71:  header( "Location: qwe.php?task=" . $par );

Как отладить скрипт чтоб он работал?

Автор: Каролина 4.1.2007, 17:53
Между прочим,я вроде делаю всё правильно но у меня вылетают те же самые ошибки... smile 

Автор: PARROT 4.1.2007, 17:59
Звездочку не надо брать в тильды, поэтому и ошибка.
Код

$result = mysql_query( "SELECT `*` FROM `auth_members`

Пользуйтесь буферизацией и будет вам счастье. И еще поиском.

Добавлено @ 18:03 
Цитата(Каролина @  4.1.2007,  17:53 Найти цитируемый пост)
делаю всё правильно

Так не бывает.

Автор: Mal Hack 4.1.2007, 18:06
Значит-ся так (с) Жеглов...

1. Вводим в поиск на форуме строку "qwe.php" и читаем темы.
2. Для отладки ошибок MySQL читаем это: http://vingrad.ru/PHP-PHPDBMYSQL-002847
3. Для отладки скрипта читаем: http://wboard.ru/topic310.html и http://wboard.ru/topic262.html
4. Ваше нежелание самому что-то сделать вам не поможет...

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

Добавлено @ 18:06 
Цитата(PARROT @  4.1.2007,  17:59 Найти цитируемый пост)
Звездочку не надо брать в тильды, поэтому и ошибка.

Это считается хорошим тоном, но на 4.1 MySQL не работает, точнее иногда не работает.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)