« Поставить закладку » « Сделать стартовой »

« Форумы » « Блоги » « Статьи » « Новости » « Файлы » « Realcoding IRC » « Site map » « Поиск »


Главная Главная
Анонсы Анонсы
Форумы Форумы
Каталог Каталог
Поиск Поиск
Опросы Опросы
Книжный магазин Книжный магазин
Реклама на сайте
Публикации Публикации
Партнеры Партнеры
Карта Карта сайта
Рассылки Рассылки
RSS экспорт
Настройки Настройки
О нас пишут О нас пишут
Контакты Контакты
Гостевая книга Гостевая книга


ПнВтСрЧтПтСбВс
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
    Популярное
Функция AccessResource

Приложение 2 Вспомогательный код для Windows

Организация поточной обработки с параметрами

Функция SetActiveWindow

Notepad++ 4.9.1

Настройка OSPF на не броадкастовых каналах

Создание консольного приложения

Использование модуля

Часть II. ВСПЛЫВАЮЩИЕ ОКНА

Использование Winsock контрола




    Архив файлов



    Сообщества

    Документация

    Кто на сайте
Вы не зарегистрированы.
Имя:

Пароль:

Запомнить

Регистрация позволит Вам пользоваться дополнительными сервисами.
Сейчас на сайте:
Гостей: 153
Пользователей: 0

Статьи:: Интернет технологии :: PHP :: Безопасный метод авторизации на PHP



отправить ссылку другу версия для печати  Обсудить на форуме

Безопасный метод авторизации на PHP

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



1. Модель (клиент)
Регистрация
- логин (a-z0-9)
- пароль
Вход
- логин
- пароль
Cookie
- уникальный идентификатор юзера
- хэш
Модель (сервер) MySQL
 Таблица users
   user_id (int(11))
   user_login (Varchar(30))
   user_password (varchar(32))
   user_hash (varchar(32))
   user_ip (int(10)) по умолчанию 0

При регистрации в базу данных записываеться логин пользователя и пароль(в двойном md5 шифровании)

При авторизация, сравниваеться логин и пароль, если они верны, то генерируеться случайная строка, которая хешируеться и добавляеться в БД в строку user_hash. Также записываеться IP адрес пользователя(но это у нас будет опциональным, так как кто-то сидит через Proxy, а у кого-то IP динамический... тут уже пользователь сам будет выбирать безопасность или удобство). В куки пользователя мы записываем его уникальный индетификатор и сгенерированный hash.


Почему надо хранить в куках хеш случайно сгенерированной строки, а не хеш пароля?
1. Из-за невнимательности программиста, во всей системе могут быть дырки, воспользовавшийсь этими дырками, злоумышленик может вытащить хеш пароля из БД и подставить его в свои куки, тем самым получить доступ к закрытым данным. В нашем же случае, двойной хеш пароля не чем не сможет помочь хакеру, так как расшифровать он его не сможет(теоретически это возможно, но на это он потратит не один месяц, а может быть и год) а воспользоваться этим хешем ему негде, ведь у нас при авторизации свой уникальный хеш прикрепленный к IP пользователя.
2. Если злоумышленик вытащит трояном у пользователя уникальный хеш, воспользовать им он также не сможет(разве если только, пользователь решил принебречь своей безопастностью и выключил привязку к IP при авторизации).

2. Практика
--
— Структура таблицы `users`

CREATE TABLE `users` (
`user_id` int(11) unsigned NOT NULL auto_increment,
`user_login` varchar(30) NOT NULL,
`user_password` varchar(32) NOT NULL,
`user_hash` varchar(32) NOT NULL,
`user_ip` int(10) unsigned NOT NULL default '0',
PRIMARY KEY (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251 AUTO_INCREMENT=1 ;




register.php
<?
// Страница регситрации нового пользователя

# Соединямся с БД
mysql_connect("localhost""myhost""myhost");
mysql_select_db("testtable");


if(isset(
$_POST['submit']))
{
    
$err = array();

    
# проверям логин
    
if(!preg_match("/^[a-zA-Z0-9]+$/",$_POST['login']))
    {
        
$err[] = "Логин может состоять только из букв английского алфавита и цифр";
    }
    
    if(
strlen($_POST['login']) < or strlen($_POST['login']) > 30)
    {
        
$err[] = "Логин должен быть не меньше 3-х символов и не больше 30";
    }
    
    
# проверяем, не сущестует ли пользователя с таким именем
    
$query mysql_query("SELECT COUNT(user_id) FROM users WHERE user_login='".mysql_real_escape_string($_POST['login'])."'");
    if(
mysql_result($query0) > 0)
    {
        
$err[] = "Пользователь с таким логином уже существует в базе данных";
    }
    
    
# Если нет ошибок, то добавляем в БД нового пользователя
    
if(count($err) == 0)
    {
        

        
$login $_POST['login'];
        
        
# Убераем лишние пробелы и делаем двойное шифрование
        
$password md5(md5(trim($_POST['password'])));
        
        
mysql_query("INSERT INTO users SET user_login='".$login."', user_password='".$password."'");
        
header("Location: login.php"); exit();
    }
    else
    {
        print 
"<b>При регистрации произошли следующие ошибки:</b><br>";
        foreach(
$err AS $error)
        {
            print 
$error."<br>";
        }
    }
}
?>


<form method="POST">
Логин <input name="login" type="text"><br>
Пароль <input name="password" type="password"><br>
<input name="submit" type="submit" value="Зарегистрироваться">
</form>



login.php

<?
// Страница авторизации


# Функция для генерации случайной строки
function generateCode($length=6) {
    
$chars "abcdefghijklmnopqrstuvwxyzABCDEFGHI JKLMNOPRQSTUVWXYZ0123456789";
    
$code "";
    
$clen strlen($chars) - 1;  
    
while (strlen($code) < $length) {
            
$code .= $chars[mt_rand(0,$clen)];  
    
}
    return 
$code;
}


# Соединямся с БД
mysql_connect("localhost""myhost""myhost");
mysql_select_db("testtable");

if(isset(
$_POST['submit']))
{
    
# Вытаскиваем из БД запись, у которой логин равняеться введенному
    
$query mysql_query("SELECT user_id, user_password FROM users WHERE user_login='".mysql_real_escape_string($_POST['login'])."' LIMIT 1");
    
$data mysql_fetch_assoc($query);
    
    
# Соавниваем пароли
    
if($data['user_password'] === md5(md5($_POST['password'])))
    {
        
# Генерируем случайное число и шифруем его
        
$hash md5(generateCode(10));
            
        if(!@
$_POST['not_attach_ip'])
        {
            
# Если пользователя выбрал привязку к IP
            # Переводим IP в строку
            
$insip ", user_ip=INET_ATON('".$_SERVER['REMOTE_ADDR']."')";
        }
        
        
# Записываем в БД новый хеш авторизации и IP
        
mysql_query("UPDATE users SET user_hash='".$hash."' ".$insip." WHERE user_id='".$data['user_id']."'");
        
        
# Ставим куки
        
setcookie("id"$data['user_id'], time()+60*60*24*30);
        
setcookie("hash"$hashtime()+60*60*24*30);
        
        
# Переадресовываем браузер на страницу проверки нашего скрипта
        
header("Location: check.php"); exit();
    }
    else
    {
        print 
"Вы ввели неправильный логин/пароль";
    }
}
?>
<form method="POST">
Логин <input name="login" type="text"><br>
Пароль <input name="password" type="password"><br>
Не прикреплять к IP(не безопасно) <input type="checkbox" name="not_attach_ip"><br>
<input name="submit" type="submit" value="Войти">
</form>



check.php

<?
// Скрипт проверки

# Соединямся с БД
mysql_connect("localhost""myhost""myhost");
mysql_select_db("testtable");

if (isset(
$_COOKIE['id']) and isset($_COOKIE['hash']))
{   
    
$query mysql_query("SELECT *,INET_NTOA(user_ip) FROM users WHERE user_id = '".intval($_COOKIE['id'])."' LIMIT 1");
    
$userdata mysql_fetch_assoc($query);

    if((
$userdata['user_hash'] !== $_COOKIE['hash']) or ($userdata['user_id'] !== $_COOKIE['id'])
 or ((
$userdata['user_ip'] !== $_SERVER['REMOTE_ADDR'])  and ($userdata['user_ip'] !== "0")))
    {
        
setcookie("id"""time() - 3600*24*30*12"/");
        
setcookie("hash"""time() - 3600*24*30*12"/");
        print 
"Хм, что-то не получилось";
    }
    else
    {
        print 
"Привет, ".$userdata['user_login'].". Всё работает!";
    }
}
else
{
    print 
"Включите куки";
}
?>


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

Автор: a href="http://jiexaspb.habrahabr.ru/"> http://jiexaspb.habrahabr.ru/




Рубрика: PHP




Вышел MySQL 5.1.30, первый стабильный рели....

MySQL

После публикации 29 тестовых версий анонсирован первый стабильный релиз MySQL 5.1, пригодный для промышленной эксплуатации и обеспечивающий увеличение производительности для "тяжелых" SQL запросов, по сравнению с MySQL 5.0, примерно на 15-20%. Главные новшества появившиеся в MySQL 5.1:


Подробнее... | Рубрика: MySQL | Добавлено: 28.11.2008

Тестирование параллельных программ.

Тестирование

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


Подробнее... | Рубрика: Тестирование | Добавлено: 28.11.2008

Архитектура AMD64 (EM64T).

Архитектура AMD

Аннотация. В статье кратко рассматривается архитектура AMD64 компании AMD и ее реализация EM64T компании Intel. Описаны особенности архитектуры, ее возможности, достоинства и недостатки.


Подробнее... | Рубрика: Архитектура AMD | Добавлено: 27.11.2008

Остальные статьи:

Платформа 2009. Определяя будущее
Windows Vista Bridge Sample Library - упра...
Оптимизация 64-битных программ
Подгрузка через AJAX HTML-кода, содержащег...
Обзор нового релиза самой мощной Ajax библ...
Firebug 1.3 и 1.4 alpha — что нового и инт...
Релиз Microsoft Silverlight 2.0. Что новог...
XML документация в C#
Курсоры в MySQL 5
Microsoft опубликовала подробности о сесси...
Microsoft делится подробностями о том, что...
Тестируем новый javascript от нового брауз...
MySQL Query Cache
Использование провайдеров компиляции в As...
Чего мы ждем от C# 4.0
Delphi 2009 и C++Builder 2009
Джоэл Спольски и Джеф Этвуд запустили новы...
Поиск кода Google /* что нового? */
10 jQuery скриптов для улучшения интерфейс...
Генераторы отчетов FastReport 4 и QuickRep...


Цитата дня (все,добавить):

Портал фрилансеров

работа на дому


    Рубрикатор

Программирование

C/С++
Обучение
Windows API
XAML
Моделирование
Паттерны
Visual Basic 7 .NET
WxWidgets
Функции WinApi
Функции С++
Разработка под Mac OS
Eiffel
Visual Studio 2008
UI дизайн
Алгоритмы
Конкурсные статьи
Turbo Pascal
Visual Studio
CASE-средства
Visual Studio 2005
Без VCL
Delphi
Тех. документация
Тестирование
Software Testing
ООП
TCP/IP
Google Android
Windows Installer
.NET Framework
Драйвера
C# C Sharp
Справка
Проектирование
Информ. системы
Visual Basic
Assembler
Оптимизация кода
Gtk+
Компоненты
Реинжиниринг
Управление проектами
Extreeme programming
Lotus Notes
Алгебраическое проектирование


Интернет технологии

PHP
Perl
ASP
WAP
Cookies
SSI
CGI
Web Servers
VB Script
DNS
CSS
XML
Html
Java Script
Java2ME
Firewall
Flash
.htaccess
Apache
VRML
Протоколы
Поисковые системы
Технология JAVA
Учебник по PHP
Учебник по JavaScript
Учебник по XML
Java Q&A
AJAX
DHTML
XHTML
Dreamweaver
Web 2.0
Python
Вебмастеру
Cisco
Ruby on Rails
Silverlight

Базы данных

Access
InterBase
MySQL
Oracle
ADO .NET
Основы SQL
Учебник по Access 2002
MS
Microsoft FoxPro
Доступ к данным
XML в MS SQL Server 2000
ODBC и MyODBC
Обучение
Caché
DB2
PostgresSQL
Sybase
Теория
Хранилища данных
Безопасность
Реляционные данные
MySQL и mSQL

Остальное:

Разное
Обзоры книг
Безопасность
Графика и дизайн
Юмор
Linux
Фракталы
Microsoft Axapta
Многоядерность
Сети
Microsoft Office
Работа
MS-DOS
Криптография
Графика и игроделание
Новости SDK
Системы защиты
Учебник по AutoCad
CVS
Windows XP
Windows Server 2003
Windows Vista
Windows 7
Мероприятия