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

Форум PHP

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

 

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

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

тема: Покажите безопасную Авторизацию на примере!
 
 автор: Sywooch   (03.07.2007 в 03:03)   письмо автору
 
 

Для начала попрошу не кидаться камнями и не указывать на поиск!

Перевернул весь форум и пришел у выводу, что данная тема так и не раскрыта как следует.

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

Коментарии в коде приветствуются!


ЗЫ, думаю многим пригодится.

   
 
 автор: python   (03.07.2007 в 05:15)
 
   для: Sywooch   (03.07.2007 в 03:03)
 

ну покажите ему уже ктонибудь как надо авторизацию делать :о)

   
 
 автор: Proger   (03.07.2007 в 08:55)   письмо автору
 
   для: Sywooch   (03.07.2007 в 03:03)
 

Хм... плохо искали, данный вопрос обсуждаеться практически ежедневно, просто не весь сразу а тут авторизация, тут регистрация, а вообще примеров куча в интернете например можно скачать какой-нить форум типа phpBB и исходники посмотреть =))))

   
 
 автор: cheops   (03.07.2007 в 09:42)   письмо автору
 
   для: Sywooch   (03.07.2007 в 03:03)
 

С разделением прав и регистрацией примеров действительно нет - это целое Web-приложение и достаточно объёмное, его придётся собирать из отдельных кусков.

   
 
 автор: Sywooch   (03.07.2007 в 12:56)   письмо автору
 
   для: cheops   (03.07.2007 в 09:42)
 

Вот и я о том же!

Cheops, а че если в задачах подобную тему опубликовать?

   
 
 автор: Равечка   (03.07.2007 в 13:16)   письмо автору
 
   для: Sywooch   (03.07.2007 в 12:56)
 

А смысл? Каждый проектирует приложение по своему, использует разные подходы.

   
 
 автор: Sywooch   (03.07.2007 в 13:29)   письмо автору
 
   для: Равечка   (03.07.2007 в 13:16)
 

Ну как вам сказать...
Определить наиболее защищенный, не емкий и грамотный подход!

   
 
 автор: cheops   (03.07.2007 в 15:03)   письмо автору
 
   для: Sywooch   (03.07.2007 в 12:56)
 

Вроде как для задачи не очень сложный скрипт... да и подходов действительно много, можно авторизоваться на сессии или базовой аутентификации, или cookie. Хранить данные в СУБД или файле - универсального решения нет.

   
 
 автор: Trianon   (03.07.2007 в 19:45)   письмо автору
 
   для: cheops   (03.07.2007 в 15:03)
 

>Вроде как для задачи не очень сложный скрипт...

Это смотря как посмотреть...
Схема регистрации и аутентификации, которая допускает логон по кукис, при котором ни в БД, ни в кукисах не хранятся пароли в открытом виде, в кукисах не хранится копия поля хеша пароля из БД, процедура регистрации и восстановления пароля требует подтверждения через e-mail, и не позволяет одновременно менять e-mail и пароль ...
В общем, такая практическая реализация аутентификации, которую более менее спокойно можно применять на реальном сайте без риска опозориться - это очень сложный скрипт. Куда сложнее всех ранее публиковавшихся задач.

   
 
 автор: Unkind   (04.07.2007 в 05:20)   письмо автору
 
   для: Trianon   (03.07.2007 в 19:45)
 

Вся сложность только в объеме кода. По моему личному мнению, делать это задачей не интересно. Нужно только сидеть и барабанить по клавишам.
Единственное, что может вызвать затруднения у новичков - корректная обработка данных. Но такая задача уже была.

   
 
 автор: Lotanaen   (04.07.2007 в 05:09)   письмо автору
 
   для: Sywooch   (03.07.2007 в 12:56)
 

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

   
 
 автор: Sywooch   (05.07.2007 в 15:00)   письмо автору
 
   для: Lotanaen   (04.07.2007 в 05:09)
 

Да нет у меня своего варианта!
Был бы вариант вряд ли я бы поднимал эту тему!

ЗЫ. в очередной раз тема проигнорирована. Думаю если ее не разкрыть то она каждую неделю будет клонироваться!

Спасибо всем отписавшимся.

   
 
 автор: Sywooch   (20.07.2007 в 13:46)   письмо автору
 
   для: Sywooch   (05.07.2007 в 15:00)
 

UP >> Может всеж найдутся герои :)

   
 
 автор: Buhen   (20.07.2007 в 14:09)   письмо автору
 
   для: Sywooch   (20.07.2007 в 13:46)
 

Главный файл. Например index.php



<!-- Вход в систему на сайте -->    
<?
 
if ((isset($_SESSION['login'])) AND ($_SESSION['login'] != ""))
 {
  
?>
  <TABLE border="0" width="100%"  cellpadding="0" cellspacing="0" class="navig">
  <TR height="24">
      <TD align="left">&nbsp;Здравствуйте, <? echo stripslashes($_SESSION['login']); ?></TD>
      <TD align="right"><A HREF="index.php?action=exituser" class="normlink">...Выйти&nbsp;</A></TD>
  </TR>
  </TABLE>
  <?
 
}
 else
 {
  
?>
   <TABLE border="0" width="99%"  cellpadding="0" cellspacing="0" class="navig" valign="middle">
   <TR align="left">
    <TD align="left" width="180" class="invisible_counter"><A href="index.php?page=registry" class="normlink">Регистрация</A>
    <!--Счетчик-->
    <!--begin of Top100-->
    <a href="http://top100.rambler.ru/top100/"><img src="http://counter.rambler.ru/top100.cnt?1163752" alt="Rambler's Top100" width="1" height="1" border="0" align="right"></a>
    <!--end of Top100 code-->
    </TD>
    <FORM METHOD=POST ACTION="index.php?action=checkuser">
       <TD class="authorization" align="right">Логин</TD>
       <TD><INPUT TYPE="text" NAME="login" maxlength="15" class="auth_field" SIZE="14"></TD>
       <TD class="authorization" align="center">&nbsp;Пароль</TD>
       <TD><INPUT TYPE="password" NAME="pwd" maxlength="15" class="auth_field" SIZE="14"></TD>
    <TD width="60" valign="middle"><CENTER><INPUT TYPE="submit" Value="Войти" style="cursor: hand; height: 18px; background-color: #FFFFFF; border: 1 solid #999999; font-family: Verdana; font-size: 8pt;"></CENTER></TD>
    <TD align="center" class="generatetime" width="100">Автоматически</TD>
    <TD align="center" class="generatetime">&nbsp;<INPUT TYPE="checkbox" NAME="auto_entrance" class="auth_entrance"></TD>
    <TD width="135"><INPUT TYPE="hidden" NAME="version" VALUE="1.2"></TD>
    </FORM>
   </TR>
   </TABLE>
  <?
 
}
?>



Затем: использую функции. Они у меня в отдельном файле например actions.php



function checkuser($safe_post_login, $safe_post_pwd)
{
    connect_db();
    $safe_post_login = htmlspecialchars(addslashes(trim($_POST['login'])), ENT_QUOTES);
    $safe_post_pwd = htmlspecialchars(addslashes($_POST['pwd']), ENT_QUOTES);
    $md5 = md5 ($safe_post_pwd);
    if (!get_magic_quotes_gpc())
    {
      $safe_post_login = mysql_escape_string($safe_post_login);
      $md5 = mysql_escape_string($md5);
    }
    //sleep(2);
    $query = "SELECT * FROM users WHERE login='$safe_post_login' AND pwd='$md5'";
    $result = mysql_query($query);
    if (mysql_num_rows($result) != 0)
    {
       $row = mysql_fetch_object($result);
       $_SESSION['login'] = $safe_post_login;
       $_SESSION['pwd'] = $md5;
       $_SESSION['id_login'] = $row->id_login;
       $_POST['valid'] = "<p class='authorization' align='center'>Вы успешно вошли в систему!";
       if(isset($_POST['auto_entrance']))
       {
           setcookie('login', urlencode($safe_post_login), time()+3600*24*10, '/', 'мой сайт');
           setcookie('pwd', urlencode($md5), time()+3600*24*10, '/', 'мой сайт');
       }
    }
    else
    {
     $_POST['invalid'] = "<p align='center' class='authorization'><br>Вы ввели неправильный логин/пароль. Попробуйте заново<br>";
     $_POST['brut'] = "<p align='center' class='authorization'><br>Обнаружены неоднократные попытки доступа!!!";
     //echo $safe_post_login;
}
close_db();
}

function exituser()
{
   session_unset();
   session_destroy();
   unset($_COOKIE['login']);
   unset($_COOKIE['pwd']);
   setcookie('login', '', time(), '/', 'мой сайт');
   setcookie('pwd', '', time(), '/', 'мой сайт');
   header("Location: index.php");
   exit;
}

Проверка куки стоит в самом начале index.php


function checkcookies()
{
    if ((isset($_COOKIE['login'])) AND ($_COOKIE['login'] != ""))
    {
        if(!get_magic_quotes_gpc())
        {
        $_COOKIE['login'] = mysql_escape_string($_COOKIE['login']) ;
        $_COOKIE['pwd'] = mysql_escape_string($_COOKIE['pwd']);
        }
    connect_db();
    $query = "SELECT * FROM users WHERE login='$_COOKIE[login]' AND pwd='$_COOKIE[pwd]'";
    $result = mysql_query($query);
    if (mysql_errno()!= 0)
    {
     echo "<p class='navig'>Ошибка!";    
    }
    else
    {
      if (mysql_num_rows($result) != 0)
        {
         $_SESSION['login'] = $_COOKIE['login'];
        }
        else
        {
         echo "Ошибка в блоке авторизации";
        }
    }

    close_db();
  }
}

Примечание функция connect_db(); и close_db; тоже хранятся в файле actions.php и сожержать параметры подключения к БД:



function connect_db()
{
    mysql_connect (host, user, password) or die("<p class='navig'>Ошибка соединения с сервером: " .mysql_error());
    mysql_select_db (db) or die("<p class='navig'>Ошибка соединения с базой данных : ".mysql_error());
}
function close_db()
{
 mysql_close();
}


Если вы найдете уязвимые места в моем коде сообщите. Буду рад! Это только моя реализация авторизации на моем сайте.

   
 
 автор: Trianon   (20.07.2007 в 15:04)   письмо автору
 
   для: Buhen   (20.07.2007 в 14:09)
 

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

Как-то я зарегистрировался на одном из порталов (автор которого, вероятно, применял схожие подходы к обработке данных пользователя).
Так уж получилось, что я в пароле указал кавычку. Собственно, хотел двойку напечатать, но был нажат shift.
Уже не помню, в чем там было несоответствие.
По моему, регистрацию приняли, а данные профиля поменять уже не удавалось...
Но выводило из себя такое положение вещей весьма и весьма.
И знаете, я до сих пор матюги складываю на автора этого кода, хотя сам портал весьма достойный.



Говорить же об уязвимости без обзора всего кода смысла нет.

   
 
 автор: JIEXA   (22.07.2007 в 02:23)   письмо автору
 
   для: Trianon   (20.07.2007 в 15:04)
 

а каким оброзом кавычка может помешать?

   
 
 автор: JIEXA   (22.07.2007 в 02:25)   письмо автору
 
   для: Trianon   (20.07.2007 в 15:04)
 

вообще делают просто второе поле для птоврного ввода пароля и тогда такие ошибки почти исключаются

   
 
 автор: Trianon   (23.07.2007 в 11:29)   письмо автору
 
   для: JIEXA   (22.07.2007 в 02:25)
 

Там было повторное поле.
Оба поля были заполнены одинаково.

   
 
 автор: ise-dvp   (20.07.2007 в 15:55)   письмо автору
 
   для: Sywooch   (20.07.2007 в 13:46)
 

этот файл инклюдится в index.php, либо в любой другой, где нужна авторизация


<?php
/*****************************************
*    object: autorized.php
*****************************************/

if (!defined'_VALID_XXX_' ) )    die( 'Direct Access to this location is not allowed.' );

require_once(
'autorized.inc.php');

session_start();

$autoriz getVar("autoriz",1);
$logoff getVar("logoff",1);
if (
$logoff$auth->logoff();
else 
$auth = new Autorized(getVar("login",1), getVar("psw",1));

define_USER_$auth->user_id );
define_LOGIN_$auth->login );
$UserMain = new user(_USER_);

if (
$auth->err
    
$auth->logoff();
else {    
.... 
что-нибудь запускаем для пользователя
}

?>


это класс для обработки авторизации


<?php
/*****************************************
*     autorized.inc.php
*****************************************/
if (!defined'_VALID_XXX_' ) )    die( 'Direct Access to this location is not allowed.' );

require_once(
'connection.php');

class 
Autorized {

    var 
$sid;
    var 
$user_id;
    var 
$login;
    var 
$err;
    var 
$ok;
    var 
$GetIdByLoginPsw "select id, active from users where login='%s' and psw='%s'";
    var 
$GetSession "select users.id, users.login from users join session ON users.id=session.user_id where session_id='%s' and users.active=1";
    var 
$UpdateSession "replace into session (user_id, session_id, autorized) values (%s, '%s', unix_timestamp())";
    var 
$SetLastVisit "update users set lastvisit=unix_timestamp() where id=%d";
    var 
$DeleteSession "delete from session where user_id=%s and session_id='%s'";

    function 
Autorized $login$password ) {

        
$this->sid session_id();
        
$this->ok 0;
        
        
$sql sprintf($this->GetSession$this->sid);
        
$Result RunSQL ($sql);
        
$row mysql_fetch_assoc$Result );
        if ( 
$row["id"] ) {
            
$this->user_id $row["id"];
            
$this->login $row["login"];
            
$this->ok 1;
        }
        else {
            if ( empty(
$login) or empty($password) ) 
                
$this->err 1;
            else {
                
$sql sprintf($this->GetIdByLoginPsw$login$password);
                
$Result RunSQL ($sql);
                
$row mysql_fetch_assoc$Result );
                if ( 
$row["id"] ) {
                    if ( 
$row["active"] ) {
                        
$this->user_id $row["id"];
                        
$this->login $login;
                        
$sql sprintf($this->UpdateSession$this->user_id$this->sid);
                        
ExecSQL$sql);
                        
$sql sprintf($this->SetLastVisit$this->user_id);
                        
ExecSQL$sql);

                        
define_USER_$this->user_id );
                        
define_LOGIN_$this->login );
                        
$this->ok 1;
                    }
                    else {
                        
$this->err 3;
                    }    
                }
                else
                    
$this->err 2;
            }    
        }
    } 
// Autorized

    
function logoff() {
    
        
$this->sid session_id();
        if (
$this->user_id) {
            
$sql sprintf($this->DeleteSession$this->user_id$this->sid);
            
ExecSQL$sql );
        }    
        
$this->ok 0;
        
$this->user_id 0;
        
$this->sid "";
        
$this->login "";
    } 
// logoff

}

?>


ногами, если что, не бить :)

   
 
 автор: Sywooch   (21.07.2007 в 18:19)   письмо автору
 
   для: ise-dvp   (20.07.2007 в 15:55)
 

Спасибо что поддержали :)

   
Rambler's Top100
вверх

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