Как сделать форму авторизации в html. Создаем невероятную простую систему регистрации на PHP и MySQL

Всем привет. Итак, мы изучили несколько элементов для создания форм. Пришло время объединить наши знания для решения задачи побольше. Давайте создадим самую простую форму для авторизации на сайте. Для этого нам необходимы два поля, делаем и привязываем к ним подписи.

Первое поле – для логина, второе – для пароля. И вот со вторым не все так просто. Поскольку на текущий момент оно представляет собой просто поле для ввода текста.

Результат в браузере:

Чтобы введенный в нем текст заменялся на звездочки, как это принято для поля такого типа, необходимо сделать одно простое действие. А именно, осуществить замену значения атрибута type на password :

Результат:

Кнопка отправки формы

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

Если на кнопке должна присутствовать какая-то надпись, то ее можно сделать, используя атрибут value . Задавать имя кнопке или нет – на ваше усмотрение, то если вы это сделаете, то сервер будет получать это имя, а также значение кнопки.

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

В итоге код нашей формы получится следующим:

Результат в браузере:

Итак, есть задача — сделать регистрацию в системе и возможность авторизации. Как это делать? Начнем по порядку.

Регистрация на php

Тут все просто. Делается хранилище данных для пользователей. Обычно это таблица БД. В нее входят такие поля как id, username и password. Остальные поля опциональны. Вы можете собирать e-mail пользователей, их адреса, возможные ip, время выхода в сеть, кодовые слова от банковских карт, секретные вопросы...

В общем, главное — это пара логин-пароль.

Первый важный момент — нельзя хранить пароли пользователей в открытом виде. То есть, как текст. Нельзя потому что если к БД получит доступ кто-то посторонний — он получит базу логин-паролей пользователей, что вряд ли им понравится. А если учесть что логин-пароль у многих пользователей на разных сервисах одни и те же — это ставит под угрозу и личные данные и финансы и личную переписку и все что угодно.

Пароли надо хранить в виде хэша. Хэширование — это операция, которая превращает исходные данные в какой-то слепок известной длины. Это хорошо тем, что слепок уникален. То есть, если мы изменим в исходных данных хотя бы один символ — слепок на выходе операции хэширования получится совершенно, до неузнаваемости другим. Операция хэширования необратима, то есть, из этого слепка не получится развернуть исходные данные. Этим оно и отличается от шифрования.

В MySQL и php есть одна и та же распространенная и безопасная функция хэширования — md5. Этот алгоритм принимает данные и отдает отпечаток.

Итак, мы получаем данные от пользователя, проверяем не пустые ли они, не содержат ли всяких ненужных нам символов (не ограничивайте пользователей слишком сильно). И теперь делаем запрос вроде этого:

INSERT INTO `users` (`id`,`username`,`password`) VALUES("",$quoted_username,MD5($quoted_password));

Обратите внимание — я специально обозвал переменные $quoted_ потому что перед запихиванием их в запрос их обязательно надо отэскейпить функцией mysql_real_escape_string(). Так как эта функция очень часто используется, а пишется очень длинно (люблю архитекторов пхп) — я рекомендую запихать ее в свою оболочку. Например, так:

Function quote($var) { return mysql_real_escape_string($var); }

Авторизация на php

Мы добавили нового пользователя и теперь он авторизуется. Мы рисуем ему форму логина-пароля и ловим его данные. Что дальше? Ведь пароль нам пришел в открытом виде, а в базе — хэш пароля. Придется конвертировать пароль в хэш, потом сравнивать их? Не, можно сделать проще — в один запрос.

SELECT * FROM `users` WHERE `login`=$qoted_login AND `password`=MD5($quoted_password);

Если запрос вернет строку — это будет строка с данными пользователя. Если нет — такого пользователя в таблице нет. Данные пользователя очень нам пригодятся — стоит их получить в ассоциативный массив.

Запомнить пользователя

Теперь нам надо запомнить что пользователь авторизован и точно знать кто это. Первое что приходит в голову — использовать для этого куки. Действительно — запихать в куки логин и id пользователя и всегда знать кто запрашивает страницу в данный момент.

Но это порочная практика. Почему? Потому что куки — это файл, который хранится у пользователя в браузере и данные из этого файла передаются серверу в каждом запросе. Во-первых, они передаются как текст, а это значит — их легко перехватить. Во-вторых, это простой текст, посылаемый пользователем. Поэтому его можно буквально переписать. Например, если мы решили хранить в куках логин пользователя "Вася" он может открыть управление куками в своем браузере, найти нужную куку и исправить ее на, скажем, "Admin". И все. Теперь при каждом запросе мы будем получать куку, которая нам будет сообщять юзернейм пользователя — "Admin".

Поэтому безопаснее хранить все данные на сервере в недоступном из веба месте. В какой-то папке, к которой нельзя получить доступ из браузера. В эту папку нужно писать все данные о пользователе и читать их оттуда каждый раз, когда он запрашивает документ. Чтобы узнать какому пользователю принадлежит какой файл данных — надо обзывать файл уникальным именем и вот это имя кидать уже пользователю в куки. Таким образом, пользователь не сможет узнать как называется файл для пользователя Admin — этот файл генерирует система на сервере. И это позволяет таскать от документа к документу хоть пароли в открытом виде.

То что я описал — это механизм сессии . В Perl, например, для использования сессий нужно загружать модули. А в php сессии поддерживаются из коробки. Фактически, все что вам нужно знать — это функция session_start() и массив $_SESSION. Это все. Сейчас расскажу.

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

Чтобы записать в сессию данные нужно просто записать их в массив $_SESSION. Сейчас нам надо помнить id юзера.

$_SESSION["userid"] = $userinfo["id"];

Все. Теперь каждый раз когда пользователь будет запрашивать скрипт, который использует сессии — вам будет доступно значение элемента $_SESSION["userid"].

Поэтому когда пользователь ввел логин и пароль, мы получили его данные из БД, что подтверждает что такой пользователь есть в нашей базе данных, мы запоминаем его в сессии.

Узнать авторизован ли пользователь

Ну это уж проще простого! Теперь, когда вы знаете как работают сессии — узнать авторизован ли пользователь — дело одной строки. Вот она:

If(isset($_SESSION["userid"])) { print "пользователь авторизован"; }

Если в сессии определен id пользователя, значит он уже прошел авторизацию. Но как узнать какой именно это пользователь? Какой его логин? Дата рождения? Кодовое слово для банковской карты? Девичья фамилия матери?

Ну очевидно — сделать один запрос к таблице users. У нас же есть id этого пользователя.

SELECT * FROM `users` WHERE `id`=$quoted_userid

Как разлогинить пользователя, сделать выход

Ну это уж совсем просто. Если мы определяем авторизован ли пользователь по наличию userid в сессии, то чтобы его разлогинить нужно удалить его оттуда. Делается так:

Unset($_SESSION["userid"]);

Еще можно убить сессию для верности. Это очистит куку у пользователя и уничтожит файл сессии на сервере. При этом из нее пропадут все данные. Делается так:

Session_destroy();

На этом все. Если остались какие-то вопросы — не стесняйтесь обращаться. Более того, вы можете обратиться ко мне по icq или почте и попросить помочь с чем-нибудь. Я обычно не отказываю. Если помощь потребуется серьезная — я могу попросить небольшую оплату. Кроме того, я могу дистанционно учить вас делать сайты! Вот такой я коуч и гуру:) А если вы хотите получать уроки и трюки просто так, бесплатно — подпишитесь на RSS моего блога .

Спонсор этого поста — ibooknet.ru, который предлагает ремонт ноутбуков по приятным ценам. Лично мой ноут в порядке и надеюсь, мне не придется его чинить. Чего и вам желаю.

Все кто разрабатывает web сайты, рано или поздно сталкивается с такой задачей как авторизация и аутентификация пользователей , реализованная именно с помощью языка программирования, а не с помощью стандарта протокола http. Сегодня мы рассмотрим пример создания простой авторизации с использованием языка программирования PHP, а данные о пользователях будем хранить в базе MySQL.

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

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

Создание объектов в базе данных

Переходим к практике. Для начала создадим таблицу хранения данных о пользователях в базе MySQL . Я предлагаю использовать простую структуру таблицы (Вы ее, конечно, можете дополнить чем-нибудь, у меня база называется test, а таблица users ):

CREATE TABLE test.users(user_id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, user_login VARCHAR(30) NOT NULL, user_password VARCHAR(32) NOT NULL, PRIMARY KEY (user_id)) ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci;

И давайте сразу же добавим одну запись в эту таблицу:

Insert into test.users (user_login, user_password) values ("mylogin","202cb962ac59075b964b07152d234b70")

Итого у нас получилось:

  • Логин – mylogin;
  • Пароль -;

Мы пароль, конечно же, будем хранить в хешированном виде, так как хранить пароль в открытом виде, мягко сказать, не безопасно. У нас Выше хеш пароля 123, поэтому, когда будем вводить пароль в форму, мы будем забивать именно 123, а не.

Создание формы регистрации

Для того чтобы пользователь мог сам зарегистрироваться, сделайте форму, данные с которой будут посылаться на файл обработки регистрации, т.е. записываться в базу данных. Например, вот самый простой способ:

0) { $error = "Пользователь с таким логином уже есть"; } // Если нет, то добавляем нового пользователя if(!isset($error)) { $login = mysql_real_escape_string(trim(htmlspecialchars($_POST["login"]))); // Убираем пробелы и хешируем пароль $password = md5(trim($_POST["password"])); mysql_query("INSERT INTO users SET user_login="".$login."", user_password="".$password."""); echo "Вы успешно зарегистрировались с логином - ".$login; exit(); } else { // если есть такой логин, то говорим об этом echo $error; } } //по умолчанию данные будут отправляться на этот же файл print <<< html

Логин
Пароль
html; ?>

Кстати, при таком способе лучше всего для логина использовать латинские буквы (т.е. английские ), если хотите писать логин на русском, то придется немного корректировать код. Файл можете назвать как угодно (для теста я использовал reg.html ).

Примечание! Для тестирования я использую всего один файл, я его назвал mylogin.html (код файла ниже). Вы можете использовать в своих файлах и называть их как угодно, я здесь описываю сам процесс авторизации, поэтому применить его можно везде. Кстати, во всех файлах придется использовать функцию session_start(); для того чтобы Вы могли проверять авторизован пользователь или нет. И еще один момент, конечно же, пропишите свои настройки подключения к базе данных.

Создание формы авторизации

"."Вы авторизованы
Т.е. мы проверили сессию и можем открыть доступ к определенным данным"; } else { $login = ""; //проверяем куку, может он уже заходил сюда if (isset($_COOKIE["CookieMy"])){ $login = htmlspecialchars($_COOKIE["CookieMy"]); } //простая формочка print <<< html

Логин
Пароль
html; } ?>

Примечание! Если вдруг у Вас отказывает работать парсер php, т.е. на экран Вам выводится сам код php, то у Вас просто на всего не включена обработка php в файлах html. Настройки делаются в файле конфигурации web сервера httpd.conf (если apache):

AddType application/x-httpd-php .php .html

В IIS в окне «Добавление сопоставления модуля» (Add Module Mapping) добавьте к *.php еще и *.html через запятую. Это если Вы делаете у себя дома на своем web сервере, а если Вы все это делаете у хостера, то Вам придется писать им и просить внести необходимые изменения, у некоторых хостеров они уже сделаны.

Код я прокомментировал, поэтому я думаю, что все должно быть понятно. Еще раз напоминаю во всех файлах, содержимое которых Вы не хотите показывать не авторизованным пользователям, необходимо писать session_start, ну и, наверное, на этом все. Если есть вопросы, задавайте в комментариях. Удачи!

Здравствуйте! Сейчас мы попробуем реализовать самую простую регистрацию на сайте с помощью PHP + MySQL. Для этого на вашем компьютере должен быть установлен Apache. Принцип работы нашего скрипта изображен ниже.

1. Начнем с создания таблички users в базе . Она будет содержать данные пользователя (логин и пароль). Зайдем в phpmyadmin (если вы создаете базу на своем ПК http://localhost/phpmyadmin/ ). Создаем таблицу users , в ней будет 3 поля.

Я создаю ее в базе mysql, вы можете создавать в другой базе. Далее устанавливаем значения, как на рисунке:

2. Необходимо соединение с этой таблицей. Давайте создадим файл bd.php . Его содержание:

$db = mysql_connect ("ваш MySQL сервер","логин к этому серверу","пароль к этому серверу");
mysql_select_db ("имя базы, к которой подключаемся",$db);
?>

В моем случае это выглядит так:

$db = mysql_connect ("localhost","user","1234");
mysql_select_db ("mysql",$db);
?>

Сохраняем bd.php .
Отлично! У нас есть таблица в базе, соединение к ней. Теперь можно приступать к созданию странички, на которой пользователи будут оставлять свои данные.

3. Создаем файл reg.php с содержанием (все комментарии внутри):



Регистрация


Регистрация
















4. Создаем файл , который будет заносить данные в базу и сохранять пользователя. save_user.php (комментарии внутри):



{
}
//если логин и пароль введены, то обрабатываем их, чтобы теги и скрипты не работали, мало ли что люди могут ввести


//удаляем лишние пробелы
$login = trim($login);
$password = trim($password);
// подключаемся к базе
// проверка на существование пользователя с таким же логином
$result = mysql_query("SELECT id FROM users WHERE login="$login"",$db);
if (!empty($myrow["id"])) {
exit ("Извините, введённый вами логин уже зарегистрирован. Введите другой логин.");
}
// если такого нет, то сохраняем данные
$result2 = mysql_query ("INSERT INTO users (login,password) VALUES("$login","$password")");
// Проверяем, есть ли ошибки
if ($result2=="TRUE")
{
echo "Вы успешно зарегистрированы! Теперь вы можете зайти на сайт. Главная страница";
}
else {
echo "Ошибка! Вы не зарегистрированы.";
}
?>

5. Теперь наши пользователи могут регистрироваться! Далее необходимо сделать "дверь" для входа на сайт уже зарегистрированным пользователям. index.php (комментарии внутри) :

// вся процедура работает на сессиях. Именно в ней хранятся данные пользователя, пока он находится на сайте. Очень важно запустить их в самом начале странички!!!
session_start();
?>


Главная страница


Главная страница











Зарегистрироваться



// Проверяем, пусты ли переменные логина и id пользователя
if (empty($_SESSION["login"]) or empty($_SESSION["id"]))
{
// Если пусты, то мы не выводим ссылку
echo "Вы вошли на сайт, как гость
Эта ссылка доступна только зарегистрированным пользователям";
}
else
{

В файле index.php мы выведем ссылочку, которая будет открыта только для зарегистрированных пользователей. В этом и заключается вся суть скрипта - ограничить доступ к каким-либо данным.

6. Остался файл с проверкой введенного логина и пароля. testreg.php (комментарии внутри):

session_start();// вся процедура работает на сессиях. Именно в ней хранятся данные пользователя, пока он находится на сайте. Очень важно запустить их в самом начале странички!!!
if (isset($_POST["login"])) { $login = $_POST["login"]; if ($login == "") { unset($login);} } //заносим введенный пользователем логин в переменную $login, если он пустой, то уничтожаем переменную
if (isset($_POST["password"])) { $password=$_POST["password"]; if ($password =="") { unset($password);} }
//заносим введенный пользователем пароль в переменную $password, если он пустой, то уничтожаем переменную
if (empty($login) or empty($password)) //если пользователь не ввел логин или пароль, то выдаем ошибку и останавливаем скрипт
{
exit ("Вы ввели не всю информацию, вернитесь назад и заполните все поля!");
}
//если логин и пароль введены,то обрабатываем их, чтобы теги и скрипты не работали, мало ли что люди могут ввести
$login = stripslashes($login);
$login = htmlspecialchars($login);
$password = stripslashes($password);
$password = htmlspecialchars($password);
//удаляем лишние пробелы
$login = trim($login);
$password = trim($password);
// подключаемся к базе
include ("bd.php");// файл bd.php должен быть в той же папке, что и все остальные, если это не так, то просто измените путь

$result = mysql_query("SELECT * FROM users WHERE login="$login"",$db); //извлекаем из базы все данные о пользователе с введенным логином
$myrow = mysql_fetch_array($result);
if (empty($myrow["password"]))
{
//если пользователя с введенным логином не существует
}
else {
//если существует, то сверяем пароли
if ($myrow["password"]==$password) {
//если пароли совпадают, то запускаем пользователю сессию! Можете его поздравить, он вошел!
$_SESSION["login"]=$myrow["login"];
$_SESSION["id"]=$myrow["id"];//эти данные очень часто используются, вот их и будет "носить с собой" вошедший пользователь
echo "Вы успешно вошли на сайт! Главная страница";
}
else {
//если пароли не сошлись

Exit ("Извините, введённый вами login или пароль неверный.");
}
}
?>

Ну вот и все! Может урок и скучный, но очень полезный. Здесь показана только идея регистрации, далее Вы можете усовершенствовать ее: добавить защиту, оформление, поля с данными, загрузку аватаров, выход из аккаунта (для этого просто уничтожить переменные из сессии функцией unset ) и так далее. Удачи!

Все проверил, работает исправно!

Процесс создания системы регистрации – это довольно большой объем работы. Вам нужно написать код, который бы перепроверял валидность email-адресов, высылал email-письма с подтверждением, предлагал возможность восстановить пароль, хранил бы пароли в безопасном месте, проверял формы ввода и многое другое. Даже когда вы все это сделаете, пользователи будут регистрироваться неохотно, так как даже самая минимальная регистрация требует их активности.

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

PHP

Теперь мы готовы к тому, чтобы заняться кодом PHP. Основной функционал системы регистрации предоставляется классом User, который вы можете видеть ниже. Класс использует (), представляющую собой минималистскую библиотеку для работы с базами данных. Класс User отвечает за доступ к базам данных, генерирование token-ов для логина и их валидации. Он представляет нам простой интерфейс, который можно без труда включить в систему регистрации на ваших сайтах, основанных на PHP.

User.class.php

// Private ORM instance
private $orm;

/**
* Find a user by a token string. Only valid tokens are taken into
* consideration. A token is valid for 10 minutes after it has been generated.
* @param string $token The token to search for
* @return User
*/

Public static function findByToken($token){

// find it in the database and make sure the timestamp is correct


->where("token", $token)
->where_raw("token_validity > NOW()")
->find_one();

If(!$result){
return false;
}

Return new User($result);
}

/**
* Either login or register a user.
* @return User
*/

Public static function loginOrRegister($email){

// If such a user already exists, return it

If(User::exists($email)){
return new User($email);
}

// Otherwise, create it and return it

Return User::create($email);
}

/**
* Create a new user and save it to the database
* @param string $email The user"s email address
* @return User
*/

Private static function create($email){

// Write a new user to the database and return it

$result = ORM::for_table("reg_users")->create();
$result->email = $email;
$result->save();

Return new User($result);
}

/**
* Check whether such a user exists in the database and return a boolean.
* @param string $email The user"s email address
* @return boolean
*/

Public static function exists($email){

// Does the user exist in the database?
$result = ORM::for_table("reg_users")
->where("email", $email)
->count();

Return $result == 1;
}

/**
* Create a new user object
* @param $param ORM instance, id, email or null
* @return User
*/

Public function __construct($param = null){

If($param instanceof ORM){

// An ORM instance was passed
$this->orm = $param;
}
else if(is_string($param)){

// An email was passed
$this->
->where("email", $param)
->find_one();
}
else{

If(is_numeric($param)){
// A user id was passed as a parameter
$id = $param;
}
else if(isset($_SESSION["loginid"])){

// No user ID was passed, look into the sesion
$id = $_SESSION["loginid"];
}

$this->orm = ORM::for_table("reg_users")
->where("id", $id)
->find_one();
}

/**
* Generates a new SHA1 login token, writes it to the database and returns it.
* @return string
*/

Public function generateToken(){
// generate a token for the logged in user. Save it to the database.

$token = sha1($this->email.time().rand(0, 1000000));

// Save the token to the database,
// and mark it as valid for the next 10 minutes only

$this->orm->set("token", $token);
$this->orm->set_expr("token_validity", "ADDTIME(NOW(),"0:10")");
$this->orm->save();

Return $token;
}

/**
* Login this user
* @return void
*/

Public function login(){

// Mark the user as logged in
$_SESSION["loginid"] = $this->orm->id;

// Update the last_login db field
$this->orm->set_expr("last_login", "NOW()");
$this->orm->save();
}

/**
* Destroy the session and logout the user.
* @return void
*/

Public function logout(){
$_SESSION = array();
unset($_SESSION);
}

/**
* Check whether the user is logged in.
* @return boolean
*/

Public function loggedIn(){
return isset($this->orm->id) && $_SESSION["loginid"] == $this->orm->id;
}

/**
* Check whether the user is an administrator
* @return boolean
*/

Public function isAdmin(){
return $this->rank() == "administrator";
}

/**
* Find the type of user. It can be either admin or regular.
* @return string
*/

Public function rank(){
if($this->orm->rank == 1){
return "administrator";
}

Return "regular";
}

/**
* Magic method for accessing the elements of the private
* $orm instance as properties of the user object
* @param string $key The accessed property"s name
* @return mixed
*/

Public function __get($key){
if(isset($this->orm->$key)){
return $this->orm->$key;
}

Return null;
}
}
Token-ы генерируются при помощи алгоритма , и сохраняются в базу данных. Мы используем из MySQL для установки значения в колонку token_validity, равного 10 минутам. При валидации token, мы сообщаем движку, что нам нужен token, поле token_validity пока еще не истекло. Таким образом мы ограничиваем время, в течение которого token будет валиден.

Обратите внимание на то, что мы используем волшебный метод __get () в конце документа, чтобы получить доступ к свойствам объекта user. Это позволяет нам осуществить доступ к данным, которые хранятся в базе данных в виде свойств: $user->email, $user->token. Для примера давайте посмотрим, как мы можем использовать этот класс в следующем фрагменте кода:


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

Functions.php

Function send_email($from, $to, $subject, $message){

// Helper function for sending email

$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type: text/plain; charset=utf-8" . "\r\n";
$headers .= "From: ".$from . "\r\n";

Return mail($to, $subject, $message, $headers);
}

function get_page_url(){

// Find out the URL of a PHP file

$url = "http".(empty($_SERVER["HTTPS"])?"":"s")."://".$_SERVER["SERVER_NAME"];

If(isset($_SERVER["REQUEST_URI"]) && $_SERVER["REQUEST_URI"] != ""){
$url.= $_SERVER["REQUEST_URI"];
}
else{
$url.= $_SERVER["PATH_INFO"];
}

Return $url;
}

function rate_limit($ip, $limit_hour = 20, $limit_10_min = 10){

// The number of login attempts for the last hour by this IP address

$count_hour = ORM::for_table("reg_login_attempt")
->
->where_raw("ts > SUBTIME(NOW(),"1:00")")
->count();

// The number of login attempts for the last 10 minutes by this IP address

$count_10_min = ORM::for_table("reg_login_attempt")
->where("ip", sprintf("%u", ip2long($ip)))
->where_raw("ts > SUBTIME(NOW(),"0:10")")
->count();

If($count_hour > $limit_hour || $count_10_min > $limit_10_min){
throw new Exception("Too many login attempts!");
}
}

function rate_limit_tick($ip, $email){

// Create a new record in the login attempt table

$login_attempt = ORM::for_table("reg_login_attempt")->create();

$login_attempt->email = $email;
$login_attempt->ip = sprintf("%u", ip2long($ip));

$login_attempt->save();
}

function redirect($url){
header("Location: $url");
exit;
}
Функции rate_limit и rate_limit_tick позволяют нам ограничивать число попыток авторизации на определенный промежуток времени. Попытки авторизации записываются в базу данных reg_login_attempt. Эти функции запускаются при проведении подтверждения формы авторизации, как можно видеть в следующем фрагменте кода.

Нижеприведенный код был взят из index.php, и он отвечает за подтверждение формы авторизации. Он возвращает JSON-ответ, который управляется кодом jQuery, который мы видели в assets/js/script.js.

index.php

If(!empty($_POST) && isset($_SERVER["HTTP_X_REQUESTED_WITH"])){

// Output a JSON header

Header("Content-type: application/json");

// Is the email address valid?

If(!isset($_POST["email"]) || !filter_var($_POST["email"], FILTER_VALIDATE_EMAIL)){
throw new Exception("Please enter a valid email.");
}

// This will throw an exception if the person is above
// the allowed login attempt limits (see functions.php for more):
rate_limit($_SERVER["REMOTE_ADDR"]);

// Record this login attempt
rate_limit_tick($_SERVER["REMOTE_ADDR"], $_POST["email"]);

// Send the message to the user

$message = "";
$email = $_POST["email"];
$subject = "Your Login Link";

If(!User::exists($email)){
$subject = "Thank You For Registering!";
$message = "Thank you for registering at our site!\n\n";
}

// Attempt to login or register the person
$user = User::loginOrRegister($_POST["email"]);

$message.= "You can login from this URL:\n";
$message.= get_page_url()."?tkn=".$user->generateToken()."\n\n";

$message.= "The link is going expire automatically after 10 minutes.";

$result = send_email($fromEmail, $_POST["email"], $subject, $message);

If(!$result){
throw new Exception("There was an error sending your email. Please try again.");
}

Die(json_encode(array(
"message" => "Thank you! We\"ve sent a link to your inbox. Check your spam folder as well."
)));
}
}
catch(Exception $e){

Die(json_encode(array(
"error"=>1,
"message" => $e->getMessage()
)));
}
При успешной авторизации или регистрации, вышеприведенный код отсылает email человеку с ссылкой для авторизации. Token (лексема) становится доступной в качестве $_GET-переменной "tkn" ввиду сгенерированного URL.

index.php

If(isset($_GET["tkn"])){

// Is this a valid login token?
$user = User::findByToken($_GET["tkn"]);

// Yes! Login the user and redirect to the protected page.

$user->login();
redirect("protected.php");
}

// Invalid token. Redirect back to the login form.
redirect("index.php");
}
Запуск $user->login() создаст необходимые переменные для сессии, что позволит пользователю оставаться авторизованным при последующих входах.

Выход из системы реализуется примерно таким же образом:

Index.php

If(isset($_GET["logout"])){

$user = new User();

If($user->loggedIn()){
$user->logout();
}

Redirect("index.php");
}
В конце кода мы снова перенаправляем пользователя на index.php, поэтому параметр?logout=1 в URL исключается.

Нашему файлу index.php также потребуется защита – мы не хотим, чтобы уже авторизованные пользователи видели форму. Для этого мы используем метод $user->loggedIn():

Index.php

$user = new User();

if($user->loggedIn()){
redirect("protected.php");
}
Наконец, давайте посмотрим, как можно защитить страницу вашего сайта, и сделать ее доступной только после авторизации:

protected.php

// To protect any php page on your site, include main.php
// and create a new User object. It"s that simple!

require_once "includes/main.php";

$user = new User();

if(!$user->loggedIn()){
redirect("index.php");
}
После этой проверки вы можете быть уверены в том, что пользователь успешно авторизовался. У вас также будет доступ к данным, которые хранятся в базе данных в качестве свойств объекта $user. Чтобы вывести email пользователя и их ранг, воспользуйтесь следующим кодом:

Echo "Your email: ".$user->email;
echo "Your rank: ".$user->rank();
Здесь rank() – это метод, так как колонка rank в базе данных обычно содержит числа (0 для обычных пользователей и 1 для администраторов), и нам нужно преобразовать это все в названия рангов, что реализуется при помощи данного метода. Чтобы преобразовать обычного пользователя в администратора, просто отредактируйте запись о пользователе в phpmyadmin (либо в любой другой программе по работе с базами данных). Будучи администратором, пользователь не будет наделен какими-то особыми возможностями. Вы сами в праве выбирать, каким правами наделять администраторов.

Готово!

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