Простая аутентификация на PHP / Хабр

Что такое JWT

JWT (JSON Web Token) – это формат упаковки данных, который позволяет обеспечить безопасную передачу информации между клиентом и сервером в JSON-формате.

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

Информация будет надёжно защищена, т.к. она будет иметь цифровую подпись.

Пример: сервер генерирует токен “пользователь вошёл как администратор” и предоставляет его клиенту. Затем клиент использует этот токен для доказательства того, он он вошёл “как администратор”.

Создание API для регистрации пользователей

Нам нужно установить заголовки, чтобы файл для создания пользователей принимал только данные JSON

Создание API для входа пользователей

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

Откроем файл api/login.php и поместим в него следующий код.

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

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

Создание API для валидации JWT

Приступим к наполнению файла api/validate_token.php.

Установим правильные заголовки. Этот файл вернет вывод в формате JSON и примет запросы от указанного URL.

<?php
// заголовки
header("Access-Control-Allow-Origin: http://localhost/rest-api-authentication-example/");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Max-Age: 3600");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
 
// требуется для декодирования JWT
include_once "config/core.php";
include_once "libs/php-jwt-master/src/BeforeValidException.php";
include_once "libs/php-jwt-master/src/ExpiredException.php";
include_once "libs/php-jwt-master/src/SignatureInvalidException.php";
include_once "libs/php-jwt-master/src/JWT.php";
use FirebaseJWTJWT;
 
// получаем значение веб-токена JSON
$data = json_decode(file_get_contents("php://input"));

// получаем JWT
$jwt=isset($data->jwt) ? $data->jwt : "";

// если JWT не пуст
if($jwt) {
 
    // если декодирование выполнено успешно, показать данные пользователя
    try {
        // декодирование jwt
        $decoded = JWT::decode($jwt, $key, array("HS256"));
 
        // код ответа
        http_response_code(200);
 
        // показать детали
        echo json_encode(array(
            "message" => "Доступ разрешен.",
            "data" => $decoded->data
        ));
 
    }
 
    // если декодирование не удалось, это означает, что JWT является недействительным
    catch (Exception $e){
    
        // код ответа
        http_response_code(401);
    
        // сообщить пользователю отказано в доступе и показать сообщение об ошибке
        echo json_encode(array(
            "message" => "Доступ закрыт.",
            "error" => $e->getMessage()
        ));
    }
}
 
// показать сообщение об ошибке, если jwt пуст
else{
 
    // код ответа
    http_response_code(401);
 
    // сообщить пользователю что доступ запрещен
    echo json_encode(array("message" => "Доступ запрещён."));
}
?>

Создание интерфейса для регистрации пользователей

Мы будем использовать API, которые мы создали ранее. Все необходимые коды будут в одном файле index.html с использованием HTML, CSS и JavaScript.

Откройте файл index.html в нашей папке authentication-jwt. Поместите следующий код:

Создадим файл custom.css который мы подключили в шапке, со следующим содержимым:

Создание интерфейса для входа пользователей

Если щёлкнуть на меню «Вход» на панели навигации, отобразится форма входа.

Активация лицензии eset nod32

Чтобы активировать лицензию ESET откройте программу, далее Справка и поддержка » изменить лицензию.

Активируйте лицензию путём ввода сгенерированного лицензионного ключа в предыдущем пункте статьи.

Таким образом вы получили бесплатную лицензию антивируса ESET NOD32 на 1 месяц.

Лайфхак: каждый раз когда лицензия заканчивается, вы создаёте бесплатную временную почту, используя её создаёте учётную запись ESET и генерируете бесплатную лицензию. И так до бесконечности.

Генерация бесплатной лицензии eset nod32

Чтобы сгенерировать бесплатную лицензию ESET, сначала необходимо перейти в свой профиль:

Далее выбрать вкладку Лицензии » Генератор бесплатных лицензий » Выбрать версию ESET NOD32 и нажать кнопку Сгенерировать.

Как сделать авторизацию на php? пишем авторизацию пользователя | otus

PHP_Deep_1.4-5020-7f0114.png

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

В этой статье вы узнаете, как сделать PHP-авторизацию (authentication) на сайте с помощью данных, полученных от пользователя при регистрации. Будем использовать таблицу MySQL, а сама PHP-авторизация будет работать с применением сессий и cookie. Материал не следует рассматривать, как пошаговое руководство. Зато он помогает понять, как работает PHP-авторизация в целом.

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

Мы используем метод передачи post, который необходим. Нам ведь не нужно, чтобы в процессе PHP-авторизации пароль и логин «светились» в адресной строке.

Когда форма готова, создаём главный контроллер — наиболее важный файл сайта, лежащий в корне — index.php. Как раз он и будет запускаться во время входа. Код выглядит следующим образом:

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

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

Потом у нас идёт условие, которое проверяет, авторизован ли ты (if (login())). То есть функция возвращает нам true, если юзер вошёл на сайт. В противном случае возвращается false. Когда вернулось true, в переменную $UID записывается id юзера. Что касается переменной $admin, то в неё пишется результат работы функции is_admin($UID). Она определяет, является ли наш юзер админом, возвращая true, если это так и false в обратном случае. Потом эти 2 переменные понадобятся, чтобы вывести определённые элементы на странице.

Итак, форму PHP-авторизации можно вывести следующим условием:

Аналогичная ситуация и с переменной $admin. Последний код тоже можно поместить в файл с формой.

Если функция login() вернёт false (юзер не вошёл на сайт), мы проверим, а нажал ли он вообще на кнопку входа на сайт, которая включена в нашу форму PHP-авторизации:

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

Давайте посмотрим на алгоритм работы:

1-20219-6acf0c.jpg

А теперь рассмотрим все функции, вызываемые в коде. Вот функция входа на сайт:

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

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

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

Когда хэши совпадают, происходит авторизация с помощью скрипта. При отсутствии совпадений, возвращается ошибка.

Давайте подробно остановимся на том, что значит «авторизироваться». В нашем скрипте информация о PHP-авторизации хранится в cookie и сессии. В сессию записывается id пользователя:

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

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

С помощью функции перезаписываются поля online и last_act в базе данных. Здесь, кстати, важно убедиться, что эти поля существуют (оба имеют тип int).

Теперь посмотрим на алгоритм работы функции enter():

2-20219-e35f69.jpg

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

functionlogin(){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);returntrue;}else//иначе добавляются cookie с логином и паролем, чтобы после перезапуска браузера сессия не слетала         {$rez=mysql_query("SELECT * FROM users WHERE id='{$_SESSION['id']}'");//запрашивается строка с искомым 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);returntrue;}elsereturnfalse;}}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);returntrue;}else//если данные из cookie не подошли, эти куки удаляются             {SetCookie("login","",time()-360000,'/');SetCookie("password","",time()-360000,'/');returnfalse;}}else//если куки не существуют      {returnfalse;}}}

Возникает вопрос, почему для авторизации используем и сессию, и cookie? Всё дело в том, что при закрытии браузера сессия «умирает», а пользователь автоматически разлогинивается. А вот cookie хранятся определённое время, задаваемое нами (50 тыс. секунд).

Дальше у нас функция online(). Её нужно запускать первой на всех модулях и страницах будущего сайта. В первую очередь, она проверяет, прошёл ли пользователь PHP-авторизацию/аутентификацию, что важно для дальнейшей работы скрипта. Во вторую очередь, она выполняет обновление времени последней активности, а также помогает в перспективе выводить систему онлайн-пользователей.

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

Очередной алгоритм работы:

3-20219-7b542b.jpg

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

Когда сессия есть, а cookie почему то нет, то по id юзера мы получаем из базы данных логин и хэш пароля, потом пишем их в cookie. Возвращается true.

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

Если у нас самый печальный вариант — ни сессии, ни cookie не оказалось, возвращается false.

Сейчас глянем на функцию is_admin($UID), определяющую является ли user админом. Если вам это не надо, опустите данную функцию и её вызовы в контроллере. Но учтите, что для вывода контента на страницу для админов она бывает полезна. К тому же, она проста и основана на одном столбце в базе данных в таблице users (столбец prava, тип int).

Когда наш юзер обыкновенный пользователь, значению в столбце присваивается 0, иначе — 1. Соответственно, в первом случае вернётся false, во втором — true.

Последняя функция — это out(). Она проста и удаляет все «следы» юзера — и сессию, и cookie.

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

Итак, мы написали функциональную, но простую PHP-регистрацию/аутентификацию/авторизацию для сайта. Также заложили фундамент для дальнейших возможностей по администрированию и не только. Такая PHP-авторизация не слетит после перезапуска браузера, т. к. мы используем cookie. Предусмотрен и выход с сайта.

Источник: https://true-coder.ru/php/pishem-avtorizaciyu-na-php.html.

Показать html форму регистрации

Когда вы нажмёте на меню Регистрация на навигационной панели, отобразится форма регистрации.

Создание метода update()

Выполним запрос UPDATE, очистку данных и привязку.

Создание файла конфигурации (ядра)

Файл login.php не будет работать без файла core.php. Этот файл содержит общие настройки / переменные нашего приложения.

У нас есть переменные, используемые нашей библиотекой JWT для кодирования и декодирования токена. Значение $key должно быть вашим собственным и уникальным секретным ключом.

Вы также можете использовать exp – идентифицирует время истечения срока действия токена.

Откроем api/config/core.php и добавим следующий код.

Тест входа в систему

Введём следующий URL запрос:

В Body вставьте следующее значение JSON.

Нам нужно сохранить сгенерированный JWT чтобы потом его использовать для проверки.

Для проверки на неудачный вход в систему измените значение пароля на 222 (это неверный пароль).

Тест на успешный доступ

Введём следующий URL:

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

Так должно выглядеть в POSTMAN:

Чтобы проверить наличие неудачного доступа, просто добавьте слово «EDITED» в свой JWT. Это сделает JWT неправильным и приведет к отказу в доступе. Это должно выглядеть так.

Тест успешного обновления пользователя

Введём следующий URL в POSTMAN.

В разделе Body изменим информацию о текущем пользователе с помощью веб-токена JSON, который мы получили ранее (и сохранили).

Должно выглядеть примерно так.

При обновлении информации о пользователе происходит генерация нового токена JWT.

Чтобы проверить, не удалось ли обновить пользователя, вы можете просто добавить слово EDITED в правленную JWT, или просто удалить JWT. Это должно выглядеть следующим образом.

Формы авторизации и регистрации

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

formreg.php:

Заключение

Итого:

Похожее:  Как сделать авторизацию на сайте через социальные сети.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *