Разное

Cookie авторизация php – Авторизация пользователей через куки (cookie)

Пишем свою авторизацию на PHP и MySQL -Будни программиста

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

И так, в базе у нас будет 1 база из 4 полей: users_id, users_login, users_password и users_hash. SQL запрос:

1
2
3
4
5
6
7

CREATE TABLE IF NOT EXISTS `users` (
  `users_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  `users_login` VARCHAR(30) NOT NULL,
  `users_password` VARCHAR(32) NOT NULL,
  `users_hash` VARCHAR(32) NOT NULL,
  PRIMARY KEY  (`users_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

    Сам скрипт авторизации будет тоже на 4 файлах. А именно:

  • conf.php — Файл конфигурации, в котором так же содержится подключение к бд;
  • register.php — Регистрация нового пользователя;
  • login.php — Авторизация пользователя;
  • check.php — Скрипт проверки авторизации;

Давайте разберем каждый файл.

conf.php

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

<?php
# настройки
define (‘DB_HOST’, ‘localhost’);
define (‘DB_LOGIN’, ‘example_user’);
define (‘DB_PASSWORD’, ‘example_password’);
define (‘DB_NAME’, ‘example_base’);
mysql_connect(DB_HOST, DB_LOGIN, DB_PASSWORD) or die («MySQL Error: » . mysql_error());
mysql_query(«set names utf8») or die («<br>Invalid query: » . mysql_error());
mysql_select_db(DB_NAME) or die («<br>Invalid query: » . mysql_error());

# массив ошибок
$error[0] = ‘Я вас не знаю’;
$error[1] = ‘Включи куки’;
$error[2] = ‘Тебе сюда нельзя’;
?>

register.php

Файл регистрации, тут содержится простейшая форма и ее обработчик. Исходный код прокомментирован, но общий процесс я коротко опишу. Вначале проверяем наш логин, он может содержать только английские буквы и цифры. Далее мы проверяем длину логина, от 3 до 30 символов. Проверяем свободен ли логин. При успешных проверках добавляем нового пользователя в базу. Из введенного пароля мы вырезаем пробелы на случай если пользователь хранит свои пароли в каком ни будь текстовом файле (в windows текстовые редакторы любят «хватать» пробелы в начале или конце выделяемого текста). Шифруем пароль в двойном MD5 и добавляем в базу данные о новом пользователе. Перебрасываем пользователя на login.php.

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

<?php
# Подключаем конфиг
include ‘conf.php’;

if(isset($_POST[‘submit’]))
{

    $err = array();

    # проверям логин
   if(!preg_match(«/^[a-zA-Z0-9]+$/»,$_POST[‘login’]))
    {
        $err[] = «Логин может состоять только из букв английского алфавита и цифр»;
    }
     
    if(strlen($_POST[‘login’]) < 3 or strlen($_POST[‘login’]) > 30)
    {
        $err[] = «Логин должен быть не меньше 3-х символов и не больше 30»;
    }
     
    # проверяем, не сущестует ли пользователя с таким именем
  $query = mysql_query(«SELECT COUNT(users_id) FROM users WHERE users_login='».mysql_real_escape_string($_POST[‘login’]).»‘»)or die («<br>Invalid query: » . mysql_error());
    if(mysql_result($query, 0) > 0)
    {
        $err[] = «Пользователь с таким логином уже существует в базе данных»;
    }
 
     
    # Если нет ошибок, то добавляем в БД нового пользователя
   if(count($err) == 0)
    {
         
        $login = $_POST[‘login’];
         
        # Убераем лишние пробелы и делаем двойное шифрование
       $password = md5(md5(trim($_POST[‘password’])));
         
        mysql_query(«INSERT INTO users SET users_login='».$login.»‘, users_password='».$password.»‘»);
        header(«Location: login.php»); exit();
    }
}
?>

  <form method=»POST» action=»»>
  Логин <input type=»text» name=»login» /><br />
  Пароль <input type=»password» name=»password» /><br />
  <input name=»submit» type=»submit» value=»Зарегистрироваться»>
  </form>
  <?php
    if (isset($err)) {
      print «<b>При регистрации произошли следующие ошибки:</b><br>»;
      foreach($err AS $error)
      {
        print $error.»<br>»;
      }  
    }
  ?>

login.php

Опять кратко расскажу о действиях совершаемых в данном скрипте. В самом начале у нас висит функция для генерации случайной строки, она служит для хеша пользователя (чуть позже более подробно). Далее мы проверяем наличие куков с ошибками (они ставятся в check.php). Подключаем файл конфигурации и проверяем пользователя. Вытаскиваем из бд логин и пароль, сравниваем с введенными и генерируем хеш. Записываем в бд новый хеш пользователя и ставим куки. В куках находится id и хеш пользователя. Пересылаем пользователя на check.php.

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

<?php
  # Функция для генерации случайной строки
  function generateCode($length=6) {
    $chars = «abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPRQSTUVWXYZ0123456789»;
    $code = «»;
    $clen = strlen($chars) — 1;  
    while (strlen($code) < $length) {
        $code .= $chars[mt_rand(0,$clen)];  
    }
    return $code;
  }
 
  # Если есть куки с ошибкой то выводим их в переменную и удаляем куки
  if (isset($_COOKIE[‘errors’])){
      $errors = $_COOKIE[‘errors’];
      setcookie(‘errors’, », time() — 60*24*30*12, ‘/’);
  }

  # Подключаем конфиг
  include ‘conf.php’;

  if(isset($_POST[‘submit’]))
  {
   
    # Вытаскиваем из БД запись, у которой логин равняеться введенному
    $data = mysql_fetch_assoc(mysql_query(«SELECT users_id, users_password FROM `users` WHERE `users_login`='».mysql_real_escape_string($_POST[‘login’]).»‘ LIMIT 1″));
     
    # Соавниваем пароли
    if($data[‘users_password’] === md5(md5($_POST[‘password’])))
    {
      # Генерируем случайное число и шифруем его
      $hash = md5(generateCode(10));
           
      # Записываем в БД новый хеш авторизации и IP
      mysql_query(«UPDATE users SET users_hash='».$hash.»‘ WHERE users_id='».$data[‘users_id’].»‘») or die(«MySQL Error: » . mysql_error());
       
      # Ставим куки
      setcookie(«id», $data[‘users_id’], time()+60*60*24*30);
      setcookie(«hash», $hash, time()+60*60*24*30);
       
      # Переадресовываем браузер на страницу проверки нашего скрипта
      header(«Location: check.php»); exit();
    }
    else
    {
      print «Вы ввели неправильный логин/пароль<br>»;
    }
  }
?>
  <form method=»POST»>
  Логин <input name=»login» type=»text»><br>
  Пароль <input name=»password» type=»password»><br>
  <input name=»submit» type=»submit» value=»Войти»>
  </form>
  <?php
  # Проверяем наличие в куках номера ошибки
  if (isset($errors)) {print ‘<h5>’.$error[$errors].'</h5>’;}

  ?>

check.php

И последний файл, который содержит проверку авторизации пользователя. В начале подключаем конфиг и если существуют куки начинаем проверку, если их нет, то ставим куки с номером ошибки и отсылаем на login.php. И так проверка. Вытаскиваем из бд id и хеш. Если они не проходят проверку на соответствие с теми куками которые стоят у посетителя, то удаляем существующие куки посетителя и ставим куки с номером ошибки, пересылаем на login.php. Если же все нормально то пользователь увидит страницу.

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
32
33

<?php
# подключаем конфиг
include ‘conf.php’;  

# проверка авторизации
if (isset($_COOKIE[‘id’]) and isset($_COOKIE[‘hash’]))
{    
    $userdata = mysql_fetch_assoc(mysql_query(«SELECT * FROM users WHERE users_id = ‘».intval($_COOKIE[‘id’]).»‘ LIMIT 1″));

    if(($userdata[‘users_hash’] !== $_COOKIE[‘hash’]) or ($userdata[‘users_id’] !== $_COOKIE[‘id’]))
    {
        setcookie(‘id’, », time() — 60*24*30*12, ‘/’);
        setcookie(‘hash’, », time() — 60*24*30*12, ‘/’);
    setcookie(‘errors’, ‘1’, time() + 60*24*30*12, ‘/’);
    header(‘Location: login.php’); exit();
    }
}
else
{
  setcookie(‘errors’, ‘2’, time() + 60*24*30*12, ‘/’);
  header(‘Location: login.php’); exit();
}
?>
<!DOCTYPE html PUBLIC «-//W3C//DTD XHTML 1.0 Transitional//EN» «http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd»>
<html xmlns=»http://www.w3.org/1999/xhtml» xml:lang=»en»>
<head>
  <meta http-equiv=»Content-Type» content=»text/html;charset=UTF-8″ />
  <title></title>
</head>
<body>
  hello!
</body>
</html>

Выход

Выход можно осуществить любым удобным для вас способом просто удалив куки, допустим так:

1
2
3
4
5
6
7
8
9

<form action=»» method=»post»><input type=’submit’ name=’exit’ value=’Выйти’/></form>
<?php
if($_REQUEST[‘exit’])
  {
        setcookie(‘id’, », time() — 60*60*24*30, ‘/’);
        setcookie(‘hash’, », time() — 60*60*24*30, ‘/’);
        header(‘Location: login.php’); exit();
  }
?>

Сразу хочу предупредить о том что ваши файлы должны быть в кодировке UTF8 и БЕЗ BOM! Приятного пользования!

Теги: Cookie, MD5, MySQL, PHP, Авторизация

programmer-weekdays.ru

php — Авторизация, куки — Stack Overflow на русском








Stack Overflow на русском



  1. 0


  2. +0



    • Тур

      Начните с этой страницы, чтобы быстро ознакомиться с сайтом



    • Справка

      Подробные ответы на любые возможные вопросы



    • Мета

      Обсудить принципы работы и политику сайта



    • О нас

      Узнать больше о компании Stack Overflow



    • Бизнес

      Узнать больше о поиске разработчиков или рекламе на сайте





  3. Войти
    Регистрация



  4. текущее сообщество

ru.stackoverflow.com

Иллюстрированный самоучитель по PHP › Авторизация доступа › Авторизация с помощью Cookies [страница — 49] | Самоучители по программированию

Авторизация с помощью Cookies

Cookie – это файл в специальном формате, который присылается сервером браузеру посетителя сайта, расположенном на этом сервере (рис.8.5). Браузер, если он поддерживает cookie (и эта поддержка в нем не отключена), помещает его в особое место и впоследствии отправляет назад на сервер при поступлении от него запроса. Иными словами, cookie позволяет серверу хранить свою информацию на компьютерах посетителей и считывать ее оттуда при необходимости. (Современные стандарты безопасности предусматривают, что каждый сервер (Вернее, узел с собственным именем (любого уровня)). может получить назад только те cookie, которые были установлены лично им, так что даже о том, какие сайты еще посещал посетитель, с помощью cookie узнать нельзя.)


Рис. 8.5. Cookie изнутри

Примечание
Cookie можно установить (т. е. прислать на компьютер посетителя) и средствами РНР. Для этого используется команда SetCookie, имеющая параметры: имя cookie, информация, записанная в cookie, время жизни cookie – указывается количество секунд, после истечения которых с 1 января 1970 года cookie не должен считы-ваться с компьютера посетителя (так уж измеряется время в операционных системах типа Unix – с начала «эпохи Unix» 01.01.1970), адреса сайта и каталога на нем, где cookie должен быть действителен, и указание на протокол передачи cookie (подробнее смотрите в Описании РНР). Считать cookie можно простой командой echo («имя cookie»). Можно сказать, что, как только cookie установлен, сценариям на всех страницах того сайта, на котором он был поставлен, становится доступна переменная с тем же именем, что и у cookie, и тем содержимым, которое было записано в нем (если в файле настройки РНР установлен в on параметр register_globals)
.

Кроме того, значения cookie помещаются в массив $HTTP_COOKIE_VARS и доступны в его элементах, одноименных с именами cookie – SHTTP_COOKIE_VARS[‘umh cookie’] (если в файле настройки РНР установлен в on параметр track_vars), а в РНР версии 4.1 и выше – еще и в массив $_СOOКIЕ.

Для удаления cookie достаточно записать в него пустое значение (это сделает команда SetCookie с единственным параметром – именем cookie).

Для установки времени жизни cookie можно сначала узнать текущее «время Unix» командой time(), а потом просто прибавить к нему то количество секунд, которое cookie должен просуществовать после его установки на компьютер посетителя. Если время жизни для cookie не установлено, то он проживет до закрытия всех окон браузера посетителя.

Как и отправка заголовков командой Header, установка cookie должна предшествовать любому выводу в выдаваемый документ: как результатов выполнения команд РНР, так и простого содержимого страницы. Иначе возникнет ошибка.

Как cookie можно использовать для решения обсуждаемой в этой главе задачи – авторизации доступа? Да очень просто – запросив от посетителя логин и пароль, записать их в cookie, а потом на каждой странице «защищенной зоны» считывать их оттуда и проверять, имеются ли такие данные в файле паролей. Ну и поступать в соответствии с результатом такого сравнения – например, отправлять те браузеры, которые не смогли представить cookie с правильными логином и паролем, прямиком на страницу авторизации, посылая им с помощью РНР-функции Header заголовок Location с соответствующим параметром, как было показано выше для предыдущего варианта авторизации.

samoychiteli.ru

php с использованием сеансов или файлов cookie для авторизации пользователя

Я использую функцию hash_hmac (md5) с IP-адрес пользователя, пароль и истечение печенья даты и никто не может расшифровать мой encripted печенье код

Вы просто подписывая данные печенья со HMAC? Похоже на это. Все HMAC действительно доказывают, что сообщение не было изменено. Кроме того, ограничение IP-адресов сильно раздражает пользователей за некоторыми прокси-серверами.

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

Если вы хотите поместить конфиденциальную информацию в куки, вы должны использовать реальное шифрование здесь, не просто подписи данных. (Прочитайте: Сделайте оба.)

Если вы не можете выполнить фактическое шифрование данных, и данные настолько рискованны, что у есть для защиты от посторонних глаз, то вы не должны его отправлять печенье. Или весь ваш сайт должен быть отправлен через SSL. Или оба.

Но давайте перейдем к мясу выпуска:

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

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

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

А почему WordPress якобы сторонится сеансов … ну, WordPress не образцовом хорошего дизайна, и сделал некоторые огромные компромиссы во имя работы почти везде. Общий хостинг — это ад.

stackoverrun.com

Отправить ответ

avatar
  Подписаться  
Уведомление о