Как добавить на сайт авторизацию


Пишем авторизацию пользователя на PHP — Блог веб-разработчиков

Совсем недавно я рассказывал, как при помощи PHP написать систему регистрации для своего сайта. Такой же принцип мы использовали и в своём проекте, созданию которого посвящён раздел «Сайт с нуля» на этом блоге (сам проект я покажу вам гораздо позже). Сегодня же я опишу, как написать авторизацию на сайте, используя данные, полученные от пользователя при регистрации. То есть, будет использоваться таблица MySQL, структура которой была описана в статье про регистрацию. Поэтому я настоятельно рекомендую прежде прочитать ту статью, ибо данная статья является её непосредственным продолжением. Авторизация будет работать с использованием сессий и cookie. Также в статье будет рассмотрено несколько приятных дополнений, таких, как «разлогинивание» (выход) и время последней активности пользователя. Итак, приступим…

Для начала необходимо сверстать главную страницу сайта и поместить её в корне сайта в папку template. Для данного урока нам достаточно, чтобы в этом файле была форма ввода логина и пароля, а также кнопка «Вход». Далее приведён код этой формы:

1
 2
 3
 4
 5
 
<form action="/" method="post">
 Логин: <input type="text" name="login" />
 
 Пароль: <input type="password" name="password" />
 <input type="submit" value="Войти" name="log_in" />
 
 </form>

Файл назовём index.html.

Метод передачи post необходим. Ведь мы не хотим, чтобы при авторизации логин и пароль светились в адресной строке.

Как только форма готова, создадим самый важный файл будущего сайта — главный контроллер, т. е. файл, лежащий в корне сайта — index.php. Именно он и будет запускаться при входе на сайт. На момент написания статьи на нашем проекте код этого файла занимает 92 строки, нам же понадобится пока лишь около 25 строк. Вот его код:

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
 
<?
 include ('lib/connect.php'); //подключаемся к БД
 include ('lib/module_global.php'); //подключаем файл с глобальными функциями
 
  
 if($_GET['action'] == "out") out(); //если передана переменная action, «разавторизируем» пользователя
  
 if (login()) //вызываем функцию login, определяющую, авторизирован юзер или нет
 
 {
 $UID = $_SESSION['id']; //если юзер авторизирован, присвоим переменной $UID его id
 $admin = is_admin($UID); //определяем, админ ли юзер
 
 }
 else //если пользователь не авторизирован, то проверим, была ли нажата кнопка входа на сайт
 {
 if(isset($_POST['log_in'])) 
 {
 $error = enter(); //функция входа на сайт
 
 if (count($error) == 0) //если нет ошибок, авторизируем юзера
 {
 $UID = $_SESSION['id'];
 
 $admin = is_admin($UID);
 }
 }
 }
 include ('tpl/index.html'); //подключаем файл с формой
 
 ?>

Теперь более подробно разберёмся, как всё это работает.

В первых трёх строках мы просто подключаем файлы с функциями, которые будем использовать далее в коде. О них чуть позже. Далее проверим, был ли передан get-параметр action=out. Если он был передан, значит пользователь нажал на ссылку выхода с сайта. Вот, кстати, код этой ссылки. Добавьте его в файл с кодом формы для входа.

<a href="/?action=out">Выход</a>

Саму функцию, как и все остальные, рассмотрим позже. Сперва логика…

Далее идёт условие, проверяющее авторизирован ли ты (if (login())). Функция возвращает true в случае, если пользователь вошёл на сайт и false в противном случае. Если вернулось true, записываем в переменную $UID id юзера, а в переменную $admin — результат работы функции is_admin($UID). Данная функция определяет, является ли пользователь администратором и возвращает true, если юзер — админ и false в противном случае. В дальнейшем две эти переменные будут необходимы для вывода определённых элементов на странице. Так, следующим условием можно вывести форму авторизации:

1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 
<?
 If($UID) //если переменной нет, выводим форму
 {?>
 <form action="/" method="post">
 
 Логин: <input type="text" name="login" />
 Пароль: <input type="password" name="password" />
 
 <input type="submit" value="Войти" name="log_in" />
 </form>
 <?}
 ?>

Аналогично и с переменной $admin. Кстати, последний код можно включить в файл с формой.
Если же функция login() вернёт false, т. е. пользователь не вошёл на сайт, проверим, нажал ли он на кнопку входа на сайт в форме авторизации:

if(isset($_POST['log_in']))

Если да, запускаем функцию enter(), авторизирующую пользователя. Если ошибок не произойдёт и юзер успешно вошёл, создадим те же 2 переменные: $UID и $admin. В противном случае никакие переменные не создаются – пользователь является гостем. Алгоритм работы представлен на следующей схеме:

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

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
 
 
function enter ()
 { 
 $error = array(); //массив для ошибок 
 if ($_POST['login'] != "" && $_POST['password'] != "") //если поля заполнены 
 
 { 
 $login = $_POST['login']; 
 $password = $_POST['password'];
 
 $rez = mysql_query("SELECT * FROM users WHERE login=$login"); //запрашиваем строку из БД с логином, введённым пользователем 
 if (mysql_num_rows($rez) == 1) //если нашлась одна строка, значит такой юзер существует в БД 
 
 { 
 $row = mysql_fetch_assoc($rez); 
 if (md5(md5($password).$row['salt']) == $row['password']) //сравниваем хэшированный пароль из БД с хэшированными паролем, введённым пользователем и солью (алгоритм хэширования описан в предыдущей статье) 
 
 { 
 //пишем логин и хэшированный пароль в cookie, также создаём переменную сессии
 setcookie ("login", $row['login'], time() + 50000); 
 setcookie ("password", md5($row['login'].$row['password']), time() + 50000); 
 $_SESSION['id'] = $row['id']; //записываем в сессию id пользователя 
 
 $id = $_SESSION['id']; 
 lastAct($id); 
 return $error; 
 } 
 else //если пароли не совпали 
 
 { 
 $error[] = "Неверный пароль"; 
 return $error; 
 } 
 } 
 else //если такого пользователя не найдено в БД 
 
 { 
 $error[] = "Неверный логин и пароль"; 
 return $error; 
 } 
 } 
  
 
 else 
 { 
 $error[] = "Поля не должны быть пустыми!"; 
 return $error; 
 } 
 
 }

Первым делом, функция проверяет, заполнил ли пользователь поля для ввода логина и пароля. Если да — продолжаем работу программы, если нет — пишем в массив $error текст ошибки и возвращаем его в основную программу, которая, узнав размерность полученного массива, не авторизирует пользователя.
Если же работа функции enter() продолжится, проверим, существует ли в БД запись с таким ником, какой ввёл юзер. Если такой записи не оказалось, вернём опять же массив с соответствующей ошибкой. Если в БД есть один пользователь с таким ником, сравним введённый пароль с паролем, хранящимся в базе данных и соответствующим нашему нику.

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

Теперь объясню, что же значит «авторизироваться». В данном скрипте данные об авторизации хранятся в сессии и cookie. В сессию записываем id пользователя:

И создаём два cookie: login и password с продолжительностью жизни — 50000 секунд. В первый пишем логин, а во второй — хэш пароля.

В этой строке мы выполняем функцию, отвечающую за установку времени последней активности юзера. Вот код этой функции:

1
 2
 
function lastAct($id)
 { $tm = time(); mysql_query("UPDATE users SET online='$tm', last_act='$tm' WHERE"); }

Функция перезаписывает поля online и last_act в БД. Кстати, предварительно, необходимо убедиться в существовании этих полей. Оба они имеют тип int.

Алгоритм работы функции enter() приведён на следующей иллюстрации:

Следующая функция отвечает за проверку, авторизирован ли пользователь на сайте или нет — login().

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
 
function login () { 
 ini_set ("session.use_trans_sid", true); session_start(); if (isset($_SESSION['id']))//если сесcия есть 
 
 { 
 if(isset($_COOKIE['login']) && isset($_COOKIE['password'])) //если cookie есть, то просто обновим время их жизни и вернём true { 
 SetCookie("login", "", time() - 1, '/'); SetCookie("password","", time() - 1, '/'); 
 
 setcookie ("login", $_COOKIE['login'], time() + 50000, '/'); 
 
 setcookie ("password", $_COOKIE['password'], time() + 50000, '/'); 
 
 $id = $_SESSION['id']; 
 lastAct($id); 
 return true; 
 
 } 
 else //иначе добавим cookie с логином и паролем, чтобы после перезапуска браузера сессия не слетала 
 { 
 $rez = mysql_query("SELECT * FROM users WHEREid']}'"); //запрашиваем строку с искомым id 
 
 if (mysql_num_rows($rez) == 1) //если получена одна строка { 
 $row = mysql_fetch_assoc($rez); //записываем её в ассоциативный массив 
 
 setcookie ("login", $row['login'], time()+50000, '/'); 
 
 setcookie ("password", md5($row['login'].$row['password']), time() + 50000, '/'); 
 
 $id = $_SESSION['id'];
 lastAct($id); 
 return true; 
 
 } 
 else return false; 
 } 
 } 
 else //если сессии нет, то проверим существование cookie. Если они существуют, то проверим их валидность по БД 
 { 
 if(isset($_COOKIE['login']) && isset($_COOKIE['password'])) //если куки существуют. 
 
 { 
 $rez = mysql_query("SELECT * FROM users WHERE login='{$_COOKIE['login']}'"); //запрашиваем строку с искомым логином и паролем 
 @$row = mysql_fetch_assoc($rez); 
 
 if(@mysql_num_rows($rez) == 1 && md5($row['login'].$row['password']) == $_COOKIE['password']) //если логин и пароль нашлись в БД 
 
 { 
 $_SESSION['id'] = $row['id']; //записываем в сесиию id 
 $id = $_SESSION['id']; 
 
 lastAct($id); 
 return true; 
 } 
 else //если данные из cookie не подошли, то удаляем эти куки, ибо нахуй они такие нам не нужны 
 { 
 SetCookie("login", "", time() - 360000, '/'); 
 
 SetCookie("password", "", time() - 360000, '/'); 
 return false; 
 
 } 
 } 
 else //если куки не существуют 
 { 
 return false; 
 } 
 } 
 }

Почему для авторизации мы будем использовать и COOKIE и сессию? Дело в том, что после закрытия браузера, сессия «умирает» и пользователь автоматически разлогинивается. Cookie же хранятся определённое, задаваемое нами, время. В данном случае это 50000 секунд.

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

Функция вернёт true, если юзер авторизирован и false в противном случае. Пичём, в процессе её работы, будет обновлено время жизни cookie, а также они будут созданы, если не существуют.

Лучше всего работу функции online описывает эта иллюстрация:

Если есть сессия и cookie, мы обновляем время жизни cookie. Для этого мы их удаляем, устанавливая время смерти на одну секунду раньше текущего момента времени, а затем устанавливаем заново. Также функцией lastAct() обновлем время последней активности. Возвращаем true.

Если же сессия есть, а cookie по какой-то причине не оказалось, то по id пользователя получаем из БД логин и хэш пароля и пишем их в cookie. Возвращаем true.

Если нет сессии, проверим, быть может существуют cookie. Классический пример авторизации после перезапуска браузера — сессия слетела, но cookie-то живы. Тут уже сложнее, мы должны проверить, совпадает ли пара логин-пароль с какой-либо строкой из БД. Ведь юзер мог заменить в настройках для сайта cookie ручками или написать любую чушь. Если такая пара нашлась, создаём переменную сессии и возвращаем true. Если же пара не найдена, посылаем пользователя на йух и возвращаем false.

Последний, самый печальный вариант — когда ни сессии, ни cookie не оказалось… Возвращаем false.

Теперь обратим взор на функцию is_admin($UID). Она определяет, является ли юзер администратором сайта. Возможно, вам это не нужно, тогда можете опустить эту функцию и все её вызовы в контроллере. Но она может быть полезна для вывода какого либо контента на страницу, предназначенного для администраторов, а не для обычных пользователей. Функция простая и основана на ещё одном созданном столбце в БД в таблице users. Столбец называем prava. Тип int. Если юзер является обыкновенным пользователем, то присваиваем значению в этом столбце 0, если же этот юзер — админ, то присваиваем единицу. Следующая функция и определяет, что стоит в столбце prava; если единица, то возвращается true (пользователь – админ), иначе false.

1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 
function is_admin($id) { 
 @$rez = mysql_query("SELECT prava FROM users WHERE"); 
 
 if (mysql_num_rows($rez) == 1) 
 { 
 $prava = mysql_result($rez, 0); 
 
 if ($prava == 1) return true; 
 else return false; 
 
 } 
 else return false; 
 }

Ну и последняя, на самом деле очень лёгкая, функция — out(). Принцип её работы прост — удалить все «следы» пользователя – сессию и cookie.

1
 2
 3
 4
 5
 6
 7
 8
 
function out () { 
 session_start(); 
 $id = $_SESSION['id']; 
 
 mysql_query("UPDATE users SET online=0 WHERE"); //обнуляем поле online, говорящее, что пользователь вышел с сайта (пригодится в будущем) 
 unset($_SESSION['id']); //удаляем переменную сессии 
 SetCookie("login", ""); //удаляем cookie с логином 
 
 SetCookie("password", ""); //удаляем cookie с паролем 
 header('Location: http://'.$_SERVER['HTTP_HOST'].'/'); //перенаправляем на главную страницу сайта }

Код всех описанных функций помещаем в файл lib/module_global.php, который подключается в самом начале работы контроллера.

Таким образом, мы написали простую, однако достаточно функциональную регистрацию для своего будущего сайта. В придачу ко всему мы заложили некоторый фундамент для ещё не рассмотренных возможностей: администрирование, онлайн-пользователи, время последней активности. Также авторизация не будет слетать после перезапуска браузера, что достигнуто путём использования cookie. Кроме этого мы предусмотрели и выход с сайта.

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

Чтобы не пропустить следующие статьи, подпишитесь на RSS.

Удачи и до следующих статей.

c # - как добавить авторизацию на весь сайт MVC

Переполнение стека
  1. Около
  2. Товары
  3. Для команд
  1. Переполнение стека Общественные вопросы и ответы
  2. Переполнение стека для команд Где разработчики и технологи делятся частными знаниями с коллегами
  3. Вакансии Программирование и связанные с ним технические возможности карьерного роста
  4. Талант Нанимайте технических специалистов и создавайте свой бренд работодателя
.

c # - Добавление заголовка авторизации в веб-ссылку

Переполнение стека
  1. Около
  2. Товары
  3. Для команд
  1. Переполнение стека Общественные вопросы и ответы
  2. Переполнение стека для команд Где разработчики и технологи делятся частными знаниями с коллегами
  3. Вакансии Программирование и связанные с ним технические возможности карьерного роста
  4. Талант Нанимайте технических специалистов и создавайте свой бренд работодателя
  5. Реклама Обратитесь к разработчикам и технологам со всего мира
  6. О компании

Загрузка…

.

go - Как добавить заголовок авторизации в HTTP-запрос Angular?

Переполнение стека
  1. Около
  2. Товары
  3. Для команд
  1. Переполнение стека Общественные вопросы и ответы
  2. Переполнение стека для команд Где разработчики и технологи делятся частными знаниями с коллегами
  3. Вакансии Программирование и связанные с ним технические возможности карьерного роста
  4. Талант Нанимайте технических специалистов и создавайте свой бренд работодателя
.

c # - Как добавить авторизацию в RazorPages?

Переполнение стека
  1. Около
  2. Товары
  3. Для команд
  1. Переполнение стека Общественные вопросы и ответы
  2. Переполнение стека для команд Где разработчики и технологи делятся частными знаниями с коллегами
  3. Вакансии Программирование и связанные с ним технические возможности карьерного роста
  4. Талант Нанимайте технических специалистов и создавайте свой бренд работодателя
.

Смотрите также

Поделиться в соц. сетях

Опубликовать в Facebook
Опубликовать в Одноклассники
Вы можете оставить комментарий, или ссылку на Ваш сайт.

Оставить комментарий