Http php авторизация: PHP: HTTP-аутентификация в PHP — Manual

Содержание

Авторизация PHP с помощью JWT (веб-токены JSON)

На чтение 13 мин Просмотров 291 Опубликовано

Было время, когда единственный способ аутентифицировать себя в приложении заключался в предоставлении ваших учетных данных (обычно имени пользователя или адреса электронной почты и пароля), а затем использовался сеанс для поддержания состояния пользователя до тех пор, пока пользователь не вышел из системы. Чуть позже мы начали использовать API аутентификации. А в последнее время JWT или веб-токены JSON все чаще используются как еще один способ аутентификации запросов к серверу.

В этой статье вы узнаете, что такое JWT и как использовать их с PHP для выполнения аутентифицированных запросов пользователей.

JWT против сеансов

Но сначала, почему сеансы — не такая уж хорошая вещь? Что ж, есть три основных причины:

  • Данные хранятся на сервере в виде обычного текста.
    Несмотря на то, что данные обычно не хранятся в общей папке, любой, у кого есть достаточный доступ к серверу, может прочитать содержимое файлов сеанса.
  • Они включают запросы на чтение / запись файловой системы.
    Каждый раз, когда начинается сеанс или его данные изменяются, серверу необходимо обновить файл сеанса. То же самое происходит каждый раз, когда приложение отправляет файл cookie сеанса. Если у вас большое количество пользователей, вы можете получить медленный сервер, если не используете альтернативные варианты хранения сеансов, такие как Memcached и Redis.
  • Распределенные / кластерные приложения.
    Поскольку файлы сеансов по умолчанию хранятся в файловой системе, трудно иметь распределенную или кластерную инфраструктуру для приложений высокой доступности — тех, которые требуют использования таких технологий, как балансировщики нагрузки и кластерные серверы. Необходимо реализовать другие носители данных и особые конфигурации — и делать это с полным осознанием их последствий.

JWT

Теперь давайте начнем изучать JWT. Спецификация веб-токена JSON (RFC 7519) была впервые опубликована 28 декабря 2010 г. и последний раз обновлялась в мае 2015 г.

У JWT есть много преимуществ перед ключами API, в том числе:

  • Ключи API — это случайные строки, тогда как JWT содержат информацию и метаданные. Эта информация и метаданные могут описывать широкий спектр вещей, таких как личность пользователя, данные авторизации и срок действия токена в пределах временного интервала или по отношению к домену.
  • Для JWT не требуется централизованный орган выдачи или отзыва.
  • JWT совместимы с OAUTh3.
  • Данные JWT можно проверить.
  • У JWT есть элементы управления сроком действия.
  • JWT предназначены для сред с ограниченным пространством, таких как заголовки авторизации HTTP.
  • Данные передаются в формате JavaScript Object Notation (JSON).
  • JWT представлены с использованием кодировки Base64url/

Как выглядит JWT?

Вот пример JWT:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. eyJpYXQiOjE0MTY5MjkxMDksImp0aSI6ImFhN2Y4ZDBhOTVjIiwic2NvcGVzIjpbInJlcG8iLCJwdWJsaWNfcmVwbyJdfQ.XCEwpBGvOLma4TCoh46FU7XhUbcskygS81HE1uHLf0E

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

Заголовок JWT

Первая строка — это заголовок JWT. Это строка JSON в кодировке Base64 с кодировкой URL. Он указывает, какой криптографический алгоритм использовался для генерации подписи, и тип токена, который всегда имеет значение JWT. Алгоритм может быть, как симметричным, так и асимметричным.

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

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

Полезная нагрузка JWT

Вторая строка — это полезная нагрузка JWT. Это также строка JSON в кодировке Base64 с кодировкой URL. Он содержит несколько стандартных полей, которые называются «претензиями». Есть три типа требований: зарегистрированные, публичные и частные.

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

  • iat: отметка времени выпуска токена.
  • key: уникальная строка, которая может использоваться для проверки токена, но противоречит отсутствию централизованного органа эмитента.
  • iss: строка, содержащая имя или идентификатор эмитента. Может быть доменным именем и может использоваться для удаления токенов из других приложений.
  • nbf: отметка времени, когда токен должен считаться действительным. Должно быть равно или больше iat.
  • exp: отметка времени, когда токен должен перестать быть действительным. Должно быть больше iatи nbf.

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

Подпись JWT

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

Подпись JWT — это комбинация трех вещей:

  • заголовок JWT
  • полезная нагрузка JWT
  • секретное значение

Эти три подписаны цифровой подписью ( не зашифрованы ) с использованием алгоритма, указанного в заголовке JWT. Если мы расшифруем приведенный выше пример, у нас будут следующие строки JSON:

Заголовок JWT

{
    "alg": "HS256",
    "typ": "JWT"
}

Данные JWT

{
    "iat": 1416929109,
    "jti": "aa7f8d0a95c",
    "scopes": [
        "repo",
        "public_repo"
    ]
}

Попробуйте сами jwt. io, где вы можете поиграть с кодированием и декодированием ваших собственных JWT.

Давайте использовать JWT в приложении на основе PHP

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

Есть много способов подойти к интеграции JWT, но вот как мы это сделаем.

Все запросы к приложению, за исключением страницы входа и выхода, должны быть аутентифицированы через JWT. Если пользователь делает запрос без JWT, он будет перенаправлен на страницу входа.

После того, как пользователь заполнит и отправит форму входа, она будет отправлена ​​через JavaScript в конечную точку входа authenticate.phpв нашем приложении. Затем конечная точка извлечет учетные данные (имя пользователя и пароль) из запроса и проверит, действительны ли они.

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

В упрощенном сценарии пользователь может запросить только один ресурс — файл PHP с подходящим названием resource.php. Он ничего не сделает, просто вернет строку, содержащую текущую временную метку на момент запроса.

Есть несколько способов использовать JWT при выполнении запросов. В нашем приложении JWT будет отправлен в заголовке авторизации Bearer.

Если вы не знакомы с авторизацией на предъявителя, это форма HTTP-аутентификации, при которой токен (например, JWT) отправляется в заголовке запроса. Сервер может проверить токен и определить, следует ли предоставить доступ «носителю» токена.

Вот пример заголовка:

Authorization: Bearer ab0dde18155a43ee83edba4a4542b973

Для каждого запроса, полученного нашим приложением, PHP будет пытаться извлечь токен из заголовка Bearer. Если он присутствует, то он подтверждается. Если он действителен, пользователь увидит нормальный ответ на этот запрос. Однако, если JWT недействителен, пользователю не будет разрешен доступ к ресурсу.

Обратите внимание, что JWT не предназначен для замены файлов cookie сеанса.

Предпосылки

Для начала нам нужно, чтобы в наших системах были установлены PHP и Composer.

В корне проекта запустите composer install. Это приведет к включению Firebase PHP-JWT, сторонней библиотеки, которая упрощает работу с JWT, а также ламинаса-config, предназначенного для упрощения доступа к данным конфигурации в приложениях.

Форма входа

 

Установив библиотеку, давайте пройдемся по коду входа в authenticate.php. Сначала мы выполняем обычную настройку, гарантируя, что автозагрузчик, созданный Composer, доступен.

<?php

declare(strict_types=1);

use Firebase\JWT\JWT;

require_once('../vendor/autoload.php');

После получения формы, учетные данные проверяются в базе данных или другом хранилище данных.  Для целей этого примера мы предполагаем, что они действительны, и устанавливаем $hasValidCredentialsзначение true.

<?php



if ($hasValidCredentials) {

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

Еще одна вещь, на которую стоит обратить внимание, это то, что $secretKeyона не будет инициализирована таким образом. Скорее всего, вы установите его в среде и извлекете с помощью библиотеки, такой как phpdotenv, или в файле конфигурации. Я избегал этого в этом примере, так как хочу сосредоточиться на коде JWT.

$secretKey  = 'bGS6lzFqvvSQ8ALbOxatm7/Vk7mLQyzqaS34Q4oR1ew=';
$issuedAt   = new DateTimeImmutable();
$expire     = $issuedAt->modify('+6 minutes')->getTimestamp();      
$serverName = "your. domain.name";
$username   = "username";                                           

$data = [
    'iat'  => $issuedAt,         
    'iss'  => $serverName,       
    'nbf'  => $issuedAt,         
    'exp'  => $expire,           
    'userName' => $username,     
];

Когда данные полезной нагрузки готовы к работе, мы затем используем статический encodeметод php-jwt для создания JWT.

Метод:

  • преобразует массив в JSON
  • создать заголовки
  • подписывает полезную нагрузку
  • кодирует последнюю строку

Принимает три параметра:

  • информация о полезной нагрузке
  • секретный ключ
  • алгоритм, используемый для подписи токена

При вызове echoрезультата функции возвращается сгенерированный токен:

<?php
    
    echo JWT::encode(
        $data,
        $secretKey,
        'HS512'
    );
}

Потребление JWT

Теперь, когда у клиента есть токен, вы можете сохранить его с помощью JavaScript или любого другого механизма, который вам больше нравится.  Вот пример того, как это сделать с помощью ванильного JavaScript. В index.htmlпосле успешного представления формы, возвращаемая JWT хранятся в памяти, форма Логина скрыта, и отображается кнопка для запроса метки:

const store = {};
const loginButton = document.querySelector('#frmLogin');
const btnGetResource = document.querySelector('#btnGetResource');
const form = document.forms[0];


store.setJWT = function (data) {
  this.JWT = data;
};

loginButton.addEventListener('submit', async (e) => {
  e.preventDefault();

  const res = await fetch('/authenticate.php', {
    method: 'POST',
    headers: {
      'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8'
    },
    body: JSON.stringify({
      username: form.inputEmail.value,
      password: form.inputPassword.value
    })
  });

  if (res.status >= 200 && res. status <= 299) {
    const jwt = await res.text();
    store.setJWT(jwt);
    frmLogin.style.display = 'none';
    btnGetResource.style.display = 'block';
  } else {
    
    console.log(res.status, res.statusText);
  }
});

Использование JWT

При нажатии кнопки «Получить текущую отметку времени» выполняется запрос GET resource.php, который устанавливает JWT, полученный после аутентификации, в заголовке авторизации.

btnGetResource.addEventListener('click', async (e) => {
  const res = await fetch('/resource.php', {
    headers: {
      'Authorization': `Bearer ${store.JWT}`
    }
  });
  const timeStamp = await res.text();
  console.log(timeStamp);
});

Когда мы нажимаем кнопку, делается запрос, подобный следующему:

GET /resource.php HTTP/1.1
Host: yourhost. com
Connection: keep-alive
Accept: */*
X-Requested-With: XMLHttpRequest
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE0MjU1ODg4MjEsImp0aSI6IjU0ZjhjMjU1NWQyMjMiLCJpc3MiOiJzcC1qd3Qtc2ltcGxlLXRlY25vbTFrMy5jOS5pbyIsIm5iZiI6MTQyNTU4ODgyMSwiZXhwIjoxNDI1NTkyNDIxLCJkYXRhIjp7InVzZXJJZCI6IjEiLCJ1c2VyTmFtZSI6ImFkbWluIn19.HVYBe9xvPD8qt0wh7rXI8bmRJsQavJ8Qs29yfVbY-A0

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

Проверка JWT

Наконец, давайте посмотрим, как мы можем проверить токен в PHP. Как всегда, мы включили автозагрузчик Composer. Затем мы могли бы, при желании, проверить, был ли использован правильный метод запроса. Я пропустил код, чтобы продолжить работу с кодом, специфичным для JWT:

<?php
chdir(dirname(__DIR__));

require_once('../vendor/autoload.php');


Затем код попытается извлечь токен из заголовка Bearer.  Я сделал это с помощью preg_match. Если вы не знакомы с функцией, она выполняет сопоставление регулярного выражения в строке.

Регулярное выражение, которое я использовал здесь, будет пытаться извлечь токен из заголовка Bearer и сбросить все остальное. Если он не найден, возвращается неверный запрос HTTP 400:

if (! preg_match('/Bearer\s(\S+)/', $_SERVER['HTTP_AUTHORIZATION'], $matches)) {
    header('HTTP/1.0 400 Bad Request');
    echo 'Token not found in request';
    exit;
}

Обратите внимание, что по умолчанию, Apache не будет проходить в HTTP_AUTHORIZATIONзаголовок PHP.

Заголовок базовой авторизации является безопасным только в том случае, если ваше соединение выполняется через HTTPS, поскольку в противном случае учетные данные отправляются в виде закодированного простого текста (не зашифрованного) по сети, что является огромной проблемой безопасности.

Я полностью понимаю логику этого решения. (.+)$
RewriteRule .* — [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

Затем мы пытаемся извлечь совпавший JWT, который будет во втором элементе $matchesпеременной. Если он недоступен, значит, JWT не был извлечен, и возвращается неверный запрос HTTP 400:

$jwt = $matches[1];
if (! $jwt) {
    
    header('HTTP/1.0 400 Bad Request');
    exit;
}

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

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

$secretKey  = 'bGS6lzFqvvSQ8ALbOxatm7/Vk7mLQyzqaS34Q4oR1ew=';
$token = JWT::decode($jwt, $secretKey, ['HS512']);
$now = new DateTimeImmutable();
$serverName = "your.domain.name";

if ($token->iss !== $serverName ||
    $token->nbf > $now->getTimestamp() ||
    $token->exp < $now->getTimestamp())
{
    header('HTTP/1.1 401 Unauthorized');
    exit;
}

Если токен недействителен, потому что, например, срок действия токена истек, пользователю будет отправлен заголовок HTTP 401 Unauthorized, и сценарий завершится.

Если процесс декодирования JWT завершился неудачно, это могло быть так:

  • Количество предоставленных сегментов не соответствовало трем стандартным, как описано ранее.
  • Заголовок или полезная нагрузка не являются допустимой строкой JSON.
  • Подпись недействительна, значит, данные были подделаны!
  • nbfТребование устанавливается в JWT с меткой времени, когда ток метка времени меньше, чем это.
  • iatТребование устанавливается в JWT с меткой времени, когда ток метка времени меньше, чем это.
  • expТребование устанавливается в JWT с меткой времени, когда текущая метка времени больше, чем это.

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

Заключение

Это краткое введение в веб-токены JSON или JWT и способы их использования в приложениях на основе PHP. С этого момента вы можете попробовать реализовать JWT в своем следующем API, возможно, попробовав некоторые другие алгоритмы подписи, которые используют асимметричные ключи, такие как RS256, или интегрируя его в существующий сервер аутентификации OAUTh3 в качестве ключа API.

 

HTTP Basic Authentication или HTTP авторизация


Ромчик

5

Доброго времени суток. В данной статье мы остановимся на таком понятии как http basic authentication или http авторизация. Для чего нужна http basic authentication и как настроить http авторизацию. И в качестве примера мы сделаем HTTP авторизацию для админки WordPress. Ну что поехали.

Первое, что мы сделаем – это разберемся с понятием http авторизации.

HTTP authentication

HTTP authentication – это протокол, описанный в стандартах  HTTP 1.0/1.1. Работает следующим образом:

  1. При обращении неавторизованного пользователя к защищенному ресурсу сервер возвращает «401 Unauthorized» и добавляет заголовок «WWW-Authenticate»
  2. Браузер при получении ответа с заголовком «WWW-Authenticate» выкидывает форму для ввода логина и пароля. И в дальнейшем при обращении к данному ресурсу передает заголовок «Authorization», где хранятся данные пользователя для аутентификации.

Существуют несколько схем  http авторизации:

  • Basic
  • Digest
  • NTLM
  • Negotiate

Главное отличие – это уровень безопасности. Мы остановимся на basic – это самая небезопасная схема. Но при использовании HTTPS, является относительно безопасным.

Схема Basic является наиболее простой схемой, при которой логин и пароль передаются в заголовке «Authorization» в незашифрованном виде.

HTTP авторизация для админки WordPress

Если вы используете SSL на своем сайте, то вы можете дополнительно настроить http basic authentication для админки WordPress. А это дополнительная защита.

Небольшое отступление: у меня ОС Windows 10 и OpenServer, который расположен по адресу e:\OpenServer\

Первое, что нам необходимо сделать – это создать файл .htpasswd

Затем перейти на один из сервисов генерации пароля (или воспользоваться утилитой htpasswd у кого Linux), например https://truemisha.ru/tools/htpasswd-generator И сгенерировать пароль

Скопируем строку и вставим в только что созданный файл . htpasswd


Admin:$apr1$grwacq2z$g1Z5bNYkD0vJKF2HllrRw/

Отлично. Теперь необходимо настроить apache с помощью файла .htaccess.

Переходим в каталог с админкой, по умолчанию это wp-admin и в нем создаем файл .htaccess.

И в него помещаем следующий код:


AuthType Basic
AuthName "Input username and password"
AuthUserFile e:\OpenServer\.htpasswd
Require valid-user

Где в AuthName указываем текст сообщения, в AuthUserFile указываем путь к файлу .htpasswd.

Сохраняем и проверяем.

При попытке перейти к админке WordPress сервер запросит http авторизацию.

Если мы не введем логин и пароль, то сервер вернет ошибку «Authentication required»

Вводим логин и пароль (Логин: Admin, а пароль: admin)

И нас пустило на стандартную страницу авторизации.

И видео к данной статье:

Заключение

Мы с вами дополнительно защитили админку WordPress http авторизацией. Но помните, что мы использовали http basic authentication, а данный тип передает логин и пароль в незашифрованном виде. Используйте https. А в следующей статье мы рассмотрим как организовать http авторизацию с помощью плагина для WordPress (когда у нас нет доступа к настройкам apache). Так, что не пропускайте выхода новых статей подписавшись: VK, facebook, twitter

Понравилась статья? Поделись с друзьями.

Авторизация на сессиях PHP и MySQL -Будни программиста

Итак, как я и обещал, сегодня я расскажу как сделать свою авторизацию используя session, php и mysql. Для начала определимся что такое сессия и чем она отличается от cookie.
Session – это механизм, позволяющий однозначно идентифицировать браузер и создающий для этого браузера файл на сервере, в котором хранятся переменные сеанса.
Cookies — это механизм хранения данных броузером удаленного компьютера для идентификации возвращающихся посетителей и хранения параметров веб-страниц.
Т.е. главное различие это место хранения данных, у сессий на стороне сервера, у куков на стороне клиента, это различие критично. Если украсть у пользователя cookie довольно просто то с сессиями не все так просто. Ну а теперь перейдем к практической части а именно к написанию своей авторизации.
Для начала определим имена файлов:

  • config.php — хранит данные для подключения к Базе Данных ( далее БД )
  • functions.php — содержит в себе все функции для работы авторизации
  • join.php — простейший пример регистрации пользователя в системе
  • login.php — служит для входа в систему
  • logout.php — служит для выхода из системы
  • members.php — служит для проверки авторизации ( простейший пример «закрытой» части сайта

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

SQL дамп таблицы пользователей

1
2
3
4
5
6

CREATE TABLE users (
  id INT(5) NOT NULL AUTO_INCREMENT,
  login VARCHAR(15) DEFAULT ‘0’ ,
  password VARCHAR(15) DEFAULT ‘0’ ,
  PRIMARY KEY (id)
);

config.php

Что содержит данный файл я уже говорил, поэтому просто приведу его код.

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

<?php
# Запуск сессии
session_start();
# Служит для отладки, показывает все ошибки, предупреждения и т.д.
error_reporting(E_ALL);
# Подключение файлов с функциями
include_once(«functions.php»);
# В этом массиве далее мы будем хранить сообщения системы, т.е. ошибки.
$messages=array();
# Данные для подключения к БД
$dbhost=»localhost»;
$dbuser=»database_user»;
$dbpass=»user_password»;
$dbname=»datebase»;
# Вызываем функцию подключения к БД
connectToDB();
?>

functions.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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

<?php

function connectToDB() {
  global $link, $dbhost, $dbuser, $dbpass, $dbname;
  ($link = mysql_pconnect(«$dbhost», «$dbuser», «$dbpass»)) || die(«Couldn’t connect to MySQL»);
  mysql_select_db(«$dbname», $link) || die(«Couldn’t open db: $dbname. Error if any was: «.mysql_error() );
}

function newUser($login, $password) {
  global $link;

  $query=»INSERT INTO users (login, password) VALUES(‘$login’, ‘$password’)»;
  $result=mysql_query($query, $link) or die(«Died inserting login info into db.  Error returned if any: «.mysql_error());

  return true;
}

function displayErrors($messages) {
  print(«<b>Возникли следующие ошибки:</b>\n<ul>\n»);

  foreach($messages as $msg){
    print(«<li>$msg</li>\n»);
  }
  print(«</ul>\n»);
}

function checkLoggedIn($status){
  switch($status){
    case «yes»:
      if(!isset($_SESSION[«loggedIn»])){
        header(«Location: login.php»);
        exit;
      }
      break;
    case «no»:
      if(isset($_SESSION[«loggedIn»]) && $_SESSION[«loggedIn»] === true ){
        header(«Location: members.php»);
      }
      break;
  }
  return true;
}

function checkPass($login, $password) {
  global $link;

  $query=»SELECT login, password FROM users WHERE login=’$login’ and password=’$password'»;
  $result=mysql_query($query, $link)
    or die(«checkPass fatal error: «.[a-zA-Z0-9 ]+$»,
    «string»=>»»
  );

  if ($field_required && empty($field_data)) {
    $messages[] = «Поле $field_descr является обезательным»;
    return;
  }

  if ($field_type == «string») {
    $field_ok = true;
  } else {
    $field_ok = ereg($data_types[$field_type], $field_data);
  }

  if (!$field_ok) {
    $messages[] = «Пожалуйста введите нормальный $field_descr.»;
    return;
  }

  if ($field_ok && ($min_length > 0)) {
    if (strlen($field_data) < $min_length) {
      $messages[] = «$field_descr должен быть не короче $min_length символов.»;
      return;
    }
  }

  if ($field_ok && ($max_length > 0)) {
    if (strlen($field_data) > $max_length) {
      $messages[] = «$field_descr не должен быть длиннее $max_length символов.»;
      return;
    }
  }
}
?>

А теперь по порядку

  • function connectToDB() — служит для подключения к базе данных
  • function newUser($login, $password) — служит для создания нового пользователя в системе
  • function displayErrors($messages) — выводит массив ошибок
  • function checkLoggedIn($status) — проверяет авторизацию пользователя.
  • function checkPass($login, $password) — проверяет пользователя по БД во время авторизации
  • function cleanMemberSession($login, $password) — авторизует пользователя
  • function flushMemberSession() — выход, или если вам будет удобнее logout
  • function field_validator($field_descr, $field_data, $field_type, $min_length=»», $max_length=»», $field_required=1) — Валидатор данных, проверяет соответствие полей требованиям системы

Работу каждой функции я описывать не буду, т.к. они довольно простые, в данный момент нас интересует только логика. Если будут вопросы — спрашивайте.

join.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
include_once(«config.php»);

checkLoggedIn(«no»);

$title=»страница регистрации»;

if(isset($_POST[«submit»])){
  field_validator(«login name», $_POST[«login»], «alphanumeric», 4, 15);
  field_validator(«password», $_POST[«password»], «string», 4, 15);
  field_validator(«confirmation password», $_POST[«password2»], «string», 4, 15);

  if(strcmp($_POST[«password»], $_POST[«password2»])) {

    $messages[]=»Ваши пароли не совпадают»;
  }
 
  $query=»SELECT login FROM users WHERE login='».$_POST[«login»].»‘»;

  $result=mysql_query($query, $link) or die(«MySQL query $query failed.  Error if any: «.mysql_error());

  if( ($row=mysql_fetch_array($result)) ){
    $messages[]=»Логин \»».$_POST[«login»].»\» уже занят, попробуйте другой.»;
  }

  if(empty($messages)) {
    newUser($_POST[«login»], $_POST[«password»]);

    cleanMemberSession($_POST[«login»], $_POST[«password»]);

    header(«Location: members.php»);

  }
}
?>
<html>
<head>
<title><?php print $title; ?></title>
<meta http-equiv=»Content-Type» content=»text/html; charset=uft-8″>
</head>
<body>
<h2><?php print $title; ?></h2>
<?php
if(!empty($messages)){
  displayErrors($messages);
}
?>
<form action=»<?php print $_SERVER[«PHP_SELF»]; ?>» method=»POST»>
<table>
<tr><td>Логин:</td><td><input type=»text» name=»login»
value=»<?php print isset($_POST[«login»]) ? $_POST[«login»] : «» ; ?>»
maxlength=»15″></td></tr>
<tr><td>Пароль:</td><td><input type=»password» name=»password» value=»» maxlength=»15″></td></tr>
<tr><td>Повторить пароль:</td><td><input type=»password» name=»password2″ value=»» maxlength=»15″></td></tr>
<tr><td>&nbsp;</td><td><input name=»submit» type=»submit» value=»Submit»></td></tr>
</table>
</form>
</body>
</html>

Если кратко описать работу скрипта получится что то вроде:
1. Если уже авторизованы пересылаем на members.php ( строка 4 )
2. Если существует $_POST[‘submit’] ( если отправили данные с формы ) проверяем поля валидатором, проверяем наличие такого пользователя, если никаких ошибок нет, добавляем нового пользователя, ставим сессию и пускаем на members.php
3. Если есть ошибки — выводим
4. Выводим форму

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
58
59

<?php
include_once(«config.php»);

checkLoggedIn(«no»);

$title=»Страница авторизации»;

if(isset($_POST[«submit»])) {
  field_validator(«login name», $_POST[«login»], «alphanumeric», 4, 15);
  field_validator(«password», $_POST[«password»], «string», 4, 15);
  if($messages){
    doIndex();
    exit;
  }

    if( !($row = checkPass($_POST[«login»], $_POST[«password»])) ) {
        $messages[]=»Incorrect login/password, try again»;
    }

  if($messages){
    doIndex();
    exit;
  }

  cleanMemberSession($row[«login»], $row[«password»]);

  header(«Location: members.php»);
} else {
  doIndex();
}

function doIndex() {
  global $messages;
  global $title;
?>
<html>
<head>
<title><?php print $title; ?></title>
<meta http-equiv=»Content-Type» content=»text/html; charset=utf-8″>
</head>
<body>
<h2><?php print $title; ?></h2>
<?php
if($messages) { displayErrors($messages); }
?>
<form action=»<?php print $_SERVER[«PHP_SELF»]; ?>» method=»POST»>
<table>
<tr><td>Логин:</td><td><input type=»text» name=»login»
value=»<?php print isset($_POST[«login»]) ? $_POST[«login»] : «» ; ?>»
maxlength=»15″></td></tr>
<tr><td>Пароль:</td><td><input type=»password» name=»password» value=»» maxlength=»15″></td></tr>
<tr><td>&nbsp;</td><td><input name=»submit» type=»submit» value=»Submit»></td></tr>
</table>
</form>
</body>
</html>
<?php
}
?>

Во первых тут стоит указать что вывод html и ошибок происходит в функции doIndex() которая вызывается в некоторых случаях, это не очень удобно поэтому кто хочет переписать — милости прошу, лично я сделал это для примера, к каждому проекту я пишу собственную авторизацию и стараюсь не повторяться. Поэтому здесь только пример.
А теперь по порядку.
1. подключаем конфиг
2. если уже авторизованы пересылаем на страницу members.php ( функция checkLoggedIn с параметром no )
3. Если отправлена форма, проверяем поля валидатором, если есть ошибки вызываем функцию doIndex(), если пароли не совпадают ставим ошибку, если есть ошибки вызываем функцию doIndex(), если все в порядке ставим сессию и отправляем на members.php, иначе опять вызываем функцию doIndex()
4. Функция doIndex() выводит html код, ошибки и форму для авторизации.

logout.php

1
2
3
4
5
6

<?php
include_once(«config.php»);
checkLoggedIn(«yes»);
flushMemberSession();
header(«Location: login.php»);
?>

Тут все просто:
1. Подключаем конфиг
2. Проверяем авторизован ли пользователь
3. Уничтожаем сессию
4. Отправляем пользователя на страницу авторизации

members.php

1
2
3
4
5
6
7

<?php
include_once(«config.php»);
checkLoggedIn(«yes»);
print(«<b>».$_SESSION[«login»].»</b>! Добро пожаловать<br>\n»);
print(«Ваш пароль: <b>».$_SESSION[«password»].»</b><br>\n»);
print(«<a href=\»logout.php».»\»>Выход</a>»);
?>

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

Ну вот собственно и все, хотя все довольно просто — пожалуй это самая длинная моя статья в блоге на данный момент. Если что то не понятно — спрашивайте! И если вы нашли ошибки или есть замечания, не молчите 🙂

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

[Примеры] Авторизация (получение access и refresh token) OAuth 2.0 Яндекс и работа с API на PHP

session_start();

 

$clientId     = ‘ad71d04727ef4f4abd33afb7cfa810058332’; // ID приложения

$clientSecret = ’15a3fc22e0c04b89b9fd383dc3aa39fe007e’; // Пароль приложения

$redirectUri  = ‘http://localhost/_blog/tests/yandex-api/oauth.php’; // Адрес, на который будет переадресован пользователь после прохождения авторизации

 

// Формируем ссылку для авторизации

$params = array(

‘client_id’     => $clientId,

‘redirect_uri’  => $redirectUri,

‘response_type’ => ‘code’,

 

// Список необходимых приложению в данный момент прав доступа, разделенных пробелом.

// Права должны запрашиваться из перечня, определенного при регистрации приложения.

// Узнать допустимые права можно по ссылке https://oauth.yandex.ru/client/<client_id>/info, указав вместо <client_id> идентификатор приложения.

// Если параметр scope не передан, то токен будет выдан с правами, указанными при регистрации приложения.

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

‘scope’         => ‘webmaster:verify webmaster:hostinfo metrika:read’,

);

 

echo ‘<a href=»https://oauth.yandex.ru/authorize?’ . http_build_query( $params ) . ‘»>Авторизация через Яндекс</a>’;

 

 

if ( isset( $_GET[‘code’] ) ) {

 

// Формирование параметров (тела) POST-запроса с указанием кода подтверждения

$query = array(

‘grant_type’    => ‘authorization_code’,

‘code’          => $_GET[‘code’],

‘client_id’     => $clientId,

‘client_secret’ => $clientSecret

);

$query = http_build_query( $query );

 

// Формирование заголовков POST-запроса

$header = «Content-type: application/x-www-form-urlencoded»;

 

// Выполнение POST-запроса

$opts    = array(

‘http’ =>

array(

‘method’  => ‘POST’,

‘header’  => $header,

‘content’ => $query

)

);

$context = stream_context_create( $opts );

 

if ( ! $content = @file_get_contents( ‘https://oauth.yandex.ru/token’, false, $context ) ) {

$error = error_get_last();

throw new Exception( ‘HTTP request failed. Error: ‘ . $error[‘message’] );

}

 

$response = json_decode( $content );

 

// Если при получении токена произошла ошибка

if ( isset( $response->error ) ) {

throw new Exception( ‘При получении токена произошла ошибка. Error: ‘ . $response->error . ‘. Error description: ‘ . $response->error_description );

}

 

$accessToken = $response->access_token; // OAuth-токен с запрошенными правами или с правами, указанными при регистрации приложения.

$expiresIn   = $response->expires_in; // Время жизни токена в секундах.

 

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

// https://tech.yandex.ru/oauth/doc/dg/reference/refresh-client-docpage/#refresh-client

$refreshToken = $response->refresh_token;

 

// Сохраняем токен в сессии

$_SESSION[‘yaToken’] = array( ‘access_token’ => $accessToken, ‘refresh_token’ => $refreshToken );

 

 

} elseif ( isset( $_GET[‘error’] ) ) { // Если при авторизации произошла ошибка

 

throw new Exception( ‘При авторизации произошла ошибка. Error: ‘ . $_GET[‘error’]

                     . ‘. Error description: ‘ . $_GET[‘error_description’] );

}

Авторизация PHP с помощью JWT (JSON Web Tokens)

Было время, когда единственный способ аутентифицировать себя в приложении заключался в предоставлении ваших учетных данных (обычно имени пользователя или адреса электронной почты и пароля), а затем использовался сеанс для поддерживать состояние пользователя до тех пор, пока пользователь не выйдет из системы. Чуть позже мы начали использовать API аутентификации. А в последнее время JWT или веб-токены JSON все чаще используются как еще один способ аутентификации запросов к серверу.

Из этой статьи вы узнаете, что такое JWT и как использовать их с PHP для выполнения запросов пользователей с аутентификацией.

JWT по сравнению с сеансами

Но сначала, почему сеансы не , а — это хорошо? Что ж, есть три основных причины:

  • Данные хранятся в виде обычного текста на сервере .
    Несмотря на то, что данные обычно не хранятся в общей папке, любой, у кого есть достаточный доступ к серверу, может прочитать содержимое файлов сеанса.
  • Они включают запросы чтения / записи файловой системы .
    Каждый раз при запуске сеанса или изменении его данных серверу необходимо обновить файл сеанса. То же самое происходит каждый раз, когда приложение отправляет файл cookie сеанса. Если у вас большое количество пользователей, вы можете получить медленный сервер, если не используете альтернативные варианты хранения сеансов, такие как Memcached и Redis.
  • Распределенные / кластерные приложения .
    Поскольку файлы сеансов по умолчанию хранятся в файловой системе, трудно иметь распределенную или кластерную инфраструктуру для приложений высокой доступности — тех, которые требуют использования таких технологий, как балансировщики нагрузки и кластерные серверы.Должны быть реализованы другие носители данных и специальные конфигурации — и делать это с полным осознанием их последствий.

JWT

А теперь давайте начнем изучать JWT. Спецификация веб-токена JSON (RFC 7519) была впервые опубликована 28 декабря 2010 г. и последний раз обновлялась в мае 2015 г.

JWT имеют много преимуществ перед ключами API, в том числе:

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

  • не требуется централизованный орган выдачи или отзыва.
  • JWT совместимы с OAUTh3.
  • Данные

  • JWT можно проверить.
  • У

  • JWT есть элементы управления сроком действия.
  • JWT предназначены для сред с ограниченным пространством, таких как заголовки авторизации HTTP.
  • Данные передаются в формате JavaScript Object Notation (JSON).
  • JWT представлены с использованием кодировки Base64url

Как выглядит JWT?

Вот образец JWT:

  eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MTY5MjkxMDksImp0aSI6ImFhN2Y4ZDBhOTVjIiwic2NvcGVzIjpbInJlcG8iLCJwdWJsaWNfcmVwbyJdfQ.XCEwpBGvOLma7XufUbEswpBGvOLma7XhTohbF
  

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

Первая строка — это заголовок JWT. Это строка JSON в кодировке Base64 с кодировкой URL.Он указывает, какой криптографический алгоритм был использован для создания подписи, и тип токена, который всегда установлен на JWT . Алгоритм может быть либо симметричным , либо асимметричным .

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

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

Полезная нагрузка JWT

Вторая строка — это полезная нагрузка JWT. Это также строка JSON в кодировке Base64 с кодировкой URL. Он содержит несколько стандартных полей, которые называются «претензиями». Существует три типа требований: зарегистрированных , государственных и частных .

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

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

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

Подпись JWT

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

Подпись JWT представляет собой комбинацию трех вещей:

  • заголовок JWT
  • полезная нагрузка JWT
  • секретное значение

Эти три подписаны цифровой подписью ( не зашифрованы, ) с использованием алгоритма, указанного в заголовке JWT.Если мы расшифруем приведенный выше пример, у нас будут следующие строки JSON:

Заголовок JWT

  {
    "alg": "HS256",
    "тип": "JWT"
}
  

Данные JWT

  {
    «iat»: 1416929109,
    "jti": "aa7f8d0a95c",
    "области": [
        "репо",
        "public_repo"
    ]
}
  

Попробуйте сами jwt.io, где вы можете поиграться с кодированием и декодированием ваших собственных JWT.

Давайте использовать JWT в приложении на основе PHP

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

Есть много способов подойти к интеграции JWT, но вот как мы это сделаем.

Все запросы к приложению, за исключением страницы входа и выхода, должны быть аутентифицированы через JWT. Если пользователь сделает запрос без JWT, он будет перенаправлен на страницу входа.

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

Если да, он сгенерирует JWT и отправит его обратно клиенту. Когда клиент получает JWT, он сохранит его и будет использовать с каждым будущим запросом к приложению.

Для упрощенного сценария пользователь может запросить только один ресурс — файл PHP с метким названием resource.php . Он ничего не сделает, просто вернет строку, содержащую текущую временную метку на момент запроса.

Есть несколько способов использовать JWT при выполнении запросов. В нашем приложении JWT будет отправлен в заголовке авторизации носителя.

Если вы не знакомы с авторизацией на предъявителя, это форма аутентификации HTTP, при которой токен (например, JWT) отправляется в заголовке запроса. Сервер может проверить токен и определить, следует ли предоставить доступ «носителю» токена.

Вот пример заголовка:

  Авторизация: предъявитель ab0dde18155a43ee83edba4a4542b973
  

Для каждого запроса, полученного нашим приложением, PHP будет пытаться извлечь токен из заголовка Bearer.Если он присутствует, значит, он подтвержден. Если он действителен, пользователь увидит обычный ответ на этот запрос. Однако, если JWT недействителен, пользователю не будет разрешен доступ к ресурсу.

Обратите внимание, что JWT был , а не , предназначенным для замены файлов cookie сеанса.

Предварительные требования

Для начала нам нужно, чтобы в наших системах были установлены PHP и Composer.

В корне проекта запустите composer install . Это приведет к включению Firebase PHP-JWT, сторонней библиотеки, которая упрощает работу с JWT, а также ламинаса-config, предназначенного для упрощения доступа к данным конфигурации в приложениях

.

Форма входа

После установки библиотеки давайте пройдемся по коду входа в Authentication.php . Сначала мы выполняем обычную настройку, гарантируя, что автозагрузчик, созданный Composer, доступен.

   

После получения формы, учетные данные проверяются в базе данных или другом хранилище данных. В этом примере мы предположим, что они действительны, и установим для $ hasValidCredentials значение true.

   

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

Еще одна вещь, на которую стоит обратить внимание, это то, что секретный ключ $ не будет инициализирован таким образом. Скорее всего, вы установите его в среде и извлекете с помощью библиотеки, такой как phpdotenv, или в файле конфигурации. Я избегал этого в этом примере, так как хочу сосредоточиться на коде JWT.

Никогда не разглашайте его и не храните под контролем версий!

  $ secretKey = 'bGS6lzFqvvSQ8ALbOxatm7 / Vk7mLQyzqaS34Q4oR1ew =';
$ selectedAt = новый DateTimeImmutable ();
$ expire = $ publishedAt-> modify ('+ 6 минут') -> getTimestamp ();
$ serverName = "ваш.доменное имя";
$ username = "имя пользователя";

$ data = [
    'iat' => $ selectedAt-> getTimestamp (),
    'iss' => $ serverName,
    'nbf' => $ IssuatedAt-> getTimestamp (),
    'exp' => $ истекает,
    'userName' => $ имя пользователя,
];
  

Когда данные полезной нагрузки готовы к работе, мы теперь используем статический метод кодирования в php-jwt для создания JWT.

Метод:

  • преобразует массив в JSON
  • изготовить жатки
  • подписывает полезную нагрузку
  • кодирует последнюю строку

Принимает три параметра:

  • информация о полезной нагрузке
  • секретный ключ
  • алгоритм, используемый для подписи токена

При вызове echo для результата функции возвращается сгенерированный токен:

   

Потребление JWT

Теперь, когда у клиента есть токен, вы можете сохранить его с помощью JavaScript или любого другого механизма, который вам больше нравится.Вот пример того, как это сделать с помощью ванильного JavaScript. В файле index.html после успешной отправки формы возвращенный JWT сохраняется в памяти, форма входа скрыта и отображается кнопка для запроса метки времени:

  const store = {};
const loginButton = document.querySelector ('# frmLogin');
const btnGetResource = document.querySelector ('# btnGetResource');
const form = document.forms [0];


store.setJWT = function (data) {
  this.JWT = данные;
};

loginButton.addEventListener ('отправить', async (e) => {
  e.preventDefault ();

  const res = await fetch ('/ authenticate.php', {
    метод: 'POST',
    заголовки: {
      'Content-type': 'application / x-www-form-urlencoded; charset = UTF-8 '
    },
    body: JSON.stringify ({
      имя пользователя: form.inputEmail.value,
      пароль: form.inputPassword.value
    })
  });

  if (res.status> = 200 && res.status <= 299) {
    const jwt = ждать res.text ();
    store.setJWT (jwt);
    frmLogin.style.display = 'нет';
    btnGetResource.style.display = 'блок';
  } еще {
    
    console.log (res.status, res.statusText);
  }
});
  

Использование JWT

При нажатии кнопки «Получить текущую метку времени» выполняется запрос GET к resource.php , который устанавливает JWT, полученный после аутентификации, в заголовке авторизации.

  btnGetResource.addEventListener ('щелчок', async (e) => {
  const res = await fetch ('/ resource.php', {
    заголовки: {
      'Авторизация': `Магазин на предъявителя $ {.JWT} `
    }
  });
  const timeStamp = ждать res.text ();
  console.log (отметка времени);
});
  

Когда мы нажимаем на кнопку, делается запрос, подобный следующему:

  GET /resource.php HTTP / 1.1
Хост: yourhost.com
Подключение: keep-alive
Принимать: */*
X-Requested-с: XMLHttpRequest
Авторизация: Знаменосец eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE0MjU1ODg4MjEsImp0aSI6IjU0ZjhjMjU1NWQyMjMiLCJpc3MiOiJzcC1qd3Qtc2ltcGxlLXRlY25vbTFrMy5jOS5pbyIsIm5iZiI6MTQyNTU4ODgyMSwiZXhwIjoxNDI1NTkyNDIxLCJkYXRhIjp7InVzZXJJZCI6IjEiLCJ1c2VyTmFtZSI6ImFkbWluIn19.HVYBe9xvPD8qt0wh7rXI8bmRJsQavJ8Qs29yfVbY-A0
  

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

Проверка JWT

Наконец, давайте посмотрим, как мы можем проверить токен в PHP. Как всегда, мы добавили автозагрузчик Composer. Затем мы могли бы, при желании, проверить, был ли использован правильный метод запроса. Я пропустил код, чтобы продолжить работу с кодом, специфичным для JWT:

   

Затем код попытается извлечь маркер из заголовка Bearer. Я сделал это с помощью preg_match. Если вы не знакомы с этой функцией, она выполняет сопоставление регулярного выражения со строкой

.

Регулярное выражение, которое я здесь использовал, будет пытаться извлечь токен из заголовка Bearer и сбросить все остальное. Если он не найден, возвращается неверный запрос HTTP 400:

.

  if (! Preg_match ('/ Bearer \ s (\ S +) /', $ _SERVER ['HTTP_AUTHORIZATION'], $ соответствует)) {
    заголовок ('HTTP / 1.0 400 Bad Request ');
    echo 'Токен не найден в запросе';
    выход;
}
  

Обратите внимание, что по умолчанию Apache не передает заголовок HTTP_AUTHORIZATION в PHP. Причина этого:

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

Я полностью понимаю логику этого решения.(. +) $
RewriteRule. * - [E = HTTP_AUTHORIZATION:% {HTTP: Authorization}]

Затем мы пытаемся извлечь совпавший JWT, который будет во втором элементе переменной $ match . Если он недоступен, значит, JWT не был извлечен, и возвращается неверный запрос HTTP 400:

.

  $ jwt = $ соответствует [1];
if (! $ jwt) {
    
    заголовок ('HTTP / 1.0 400 Bad Request');
    выход;
}
  

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

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

  $ secretKey = 'bGS6lzFqvvSQ8ALbOxatm7 / Vk7mLQyzqaS34Q4oR1ew =';
$ token = JWT :: decode ($ jwt, $ secretKey, ['HS512']);
$ сейчас = новый DateTimeImmutable ();
$ serverName = "your.domain.name";

if ($ token-> iss! == $ serverName ||
    $ token-> nbf> $ now-> getTimestamp () ||
    $ токен-> exp <$ сейчас-> getTimestamp ())
{
    заголовок («HTTP / 1.1 401 Unauthorized»);
    выход;
}
  

Если токен недействителен, например, из-за того, что срок действия токена истек, пользователю будет отправлен заголовок HTTP 401 Unauthorized, и сценарий завершится.

Если процесс декодирования JWT завершился неудачно, это могло быть так:

  • Количество предоставленных сегментов не соответствует стандартным трем, как описано ранее.
  • Заголовок или полезные данные не являются допустимой строкой JSON
  • Подпись недействительна, значит, данные были подделаны!
  • Требование nbf устанавливается в JWT с меткой времени, когда текущая метка времени меньше этого.
  • Утверждение iat устанавливается в JWT с меткой времени, если текущая метка времени меньше этого значения.
  • Требование exp устанавливается в JWT с меткой времени, когда текущая метка времени больше этого.

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

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

В заключение

Это краткое введение в веб-токены JSON или JWT и их использование в приложениях на основе PHP.С этого момента вы можете попробовать реализовать JWT в своем следующем API, возможно, попробовав некоторые другие алгоритмы подписи, которые используют асимметричные ключи, такие как RS256, или интегрируя его в существующий сервер аутентификации OAUTh3 в качестве ключа API.

Если у вас есть какие-либо комментарии или вопросы, не стесняйтесь обращаться к нам в Twitter.

Как отправить запрос GET с заголовком авторизации токена носителя?

Код PHP для примера заголовка авторизации токена носителя запроса GET

Этот фрагмент кода PHP был сгенерирован автоматически для примера заголовка авторизации токена носителя запроса GET.
<< Назад к примеру заголовка авторизации токена носителя запроса GET

Что такое аутентификация на носителе?

HTTP предоставляет основу для управления доступом к защищенным ресурсам. HTTP-аутентификация выполняется путем отправки учетных данных аутентификации в заголовке авторизации для получения доступа к защищенному ресурсу. Аутентификация на предъявителя (также называемая аутентификацией токена) - это одна из схем аутентификации HTTP, которую можно понимать как предоставление доступа носителю этого токена.Аутентификация токена-носителя выполняется путем отправки токена безопасности с каждым HTTP-запросом, который мы делаем к серверу. Вы можете выполнить аутентификацию на предъявителя с любым языком программирования, включая PHP.

  Авторизация: токен-носитель {токен}  

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

Если ваш запрос не включает заголовок авторизации или содержит недопустимый токен носителя, сервер может ответить кодом состояния 401 (Неавторизованный) и предоставить информацию о том, как пройти аутентификацию с использованием заголовка WWW-Authenticate. После получения ответа 401 ваш PHP-клиент может отправить другой HTTP-запрос с допустимым заголовком авторизации.

Схема аутентификации носителя изначально была создана как часть OAuth 2.0 в RFC6750, но иногда также используется сама по себе. По соображениям безопасности токен-носитель следует отправлять только через соединения HTTPS (SSL).

Пример аутентификации токена-носителя

Пример HTTP-запроса GET с заголовком аутентификации токена-носителя, который мы отправляем на URL-адрес echo ReqBin.

Пример аутентификации токена носителя

  GET / echo / get / json HTTP / 1.1
Авторизация: предъявитель {токен}
Хост: reqbin.com
  

См. Также HTTP-аутентификация, POST JSON с заголовком авторизации токена-носителя и запрос Curl с заголовком авторизации токена-носителя.

Создание фрагментов кода для PHP и других языков программирования

Преобразуйте запрос заголовка авторизации токена носителя запроса GET в запросы PHP, JavaScript / AJAX, Curl / Bash, Python, Java, C # /.Фрагменты кода .NET с использованием генератора кода PHP.

HTTP / REST-клиенты и безопасность | Руководство по Elasticsearch [7.13]

HTTP / REST-клиенты и безопасностьedit

Функции безопасности Elasticsearch работают со стандартным HTTP
базовая аутентификация
заголовки для аутентификации пользователей. Поскольку Elasticsearch не имеет состояния, этот заголовок должен
отправляться с каждым запросом:

 Авторизация: Базовая   

<ТОКЕН> вычисляется как base64 (ИМЯ ПОЛЬЗОВАТЕЛЯ: ПАРОЛЬ)

В качестве альтернативы вы можете использовать
услуги аутентификации на основе токенов.

Примеры клиентовправить

В этом примере для создания индекса используется curl без базовой аутентификации:

 curl -XPUT 'локальный хост: 9200 / idx' 
 {
  "error": "AuthenticationException [Отсутствует токен аутентификации]",
  «статус»: 401
} 

Поскольку с указанным выше запросом не связан ни один пользователь, возникает ошибка аутентификации.
вернулся. Теперь мы будем использовать curl с базовой аутентификацией для создания индекса в качестве
rdeniro пользователь:

 curl --user rdeniro: taxidriver -XPUT 'localhost: 9200 / idx' 
Вторичная авторизация

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

 es-secondary-authorization: Базовая   

<ТОКЕН> вычисляется как base64 (ИМЯ ПОЛЬЗОВАТЕЛЯ: ПАРОЛЬ)

Заголовок es-secondary-authorization имеет тот же синтаксис, что и заголовок
Авторизация заголовок. Поэтому он также поддерживает использование
услуги аутентификации на основе токенов.Для
пример:

 es-secondary-authorization: ApiKey   

вычисляется как base64 (идентификатор ключа API: ключ API)

Клиентские библиотеки через HTTPedit

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

Базовая проверка подлинности

OAS 3 Эта страница относится к OpenAPI 3 - последней версии спецификации OpenAPI.Если вы используете OpenAPI 2 (fka Swagger), посетите страницы OpenAPI 2.

Базовая проверка подлинности

Базовая аутентификация - это простая схема аутентификации, встроенная в протокол HTTP. Клиент отправляет HTTP-запросы с заголовком Authorization , который содержит слово Basic , за которым следует пробел и строка в кодировке base64 username: password . Например, чтобы авторизоваться как demo / p @ 55w0rd , клиент отправит

  Авторизация: Базовая ZGVtbzpwQDU1dzByZA ==  

Примечание: Поскольку base64 легко декодируется, обычную проверку подлинности следует использовать только вместе с другими механизмами безопасности, такими как HTTPS / SSL.

Описание базовой аутентификации

Используя OpenAPI 3.0, вы можете описать базовую аутентификацию следующим образом:

  openapi: 3.0.0
...

составные части:
  securitySchemes:
    basicAuth: # <- произвольное имя схемы безопасности
      тип: http
      схема: базовая

безопасность:
  - basicAuth: [] # <- используйте то же имя здесь
  

Первый раздел, securitySchemes , определяет схему безопасности с именем basicAuth (произвольное имя).Эта схема должна иметь тип : http и схему : базовый . Затем раздел security применяет базовую аутентификацию ко всему API. Квадратные скобки [] обозначают используемые объемы безопасности; список пуст, поскольку обычная проверка подлинности не использует области. Безопасность можно установить глобально (как в примере выше) или на уровне операции. Последнее полезно, если только часть операций требует базовой проверки подлинности:

  путей:
  /что-нибудь:
    получать:
      безопасность:
        - basicAuth: []  

Базовую проверку подлинности также можно комбинировать с другими методами проверки подлинности, как описано в разделе Использование нескольких типов проверки подлинности.

401 Ответ

Вы также можете определить ответ 401 «Неавторизованный», возвращаемый для запросов с отсутствующими или неверными учетными данными. Этот ответ включает заголовок WWW-Authenticate , о котором вы, возможно, захотите упомянуть. Как и другие общие ответы, ответ 401 может быть определен в глобальном разделе компонентов / ответов и ссылаться в другом месте через $ ref .

  путей:
  /что-нибудь:
    получать:
      ...
      ответы:
        ...
        '401':
           $ ref: '# / components / answers / UnauthorizedError'
    Почта:
      ...
      ответы:
        ...
        '401':
          $ ref: '# / components / answers / UnauthorizedError'
...
составные части:
  ответы:
    UnauthorizedError:
      описание: информация для аутентификации отсутствует или недействительна
      заголовки:
        WWW_Authenticate:
          схема:
            тип: строка  

Дополнительные сведения о синтаксисе ответов см. В разделе Описание ответов.

Не нашли то, что искали? Задайте вопрос сообществу
Нашли ошибку? Сообщите нам

Аутентификация пользователей с помощью PHP | Google Cloud

Фон

В этом руководстве для аутентификации пользователей используется IAP.
Это только один из нескольких возможных подходов.
Узнать больше
о различных методах аутентификации пользователей см.
Раздел концепций аутентификации.

Hello

адрес электронной почты пользователя приложение

Приложение для этого руководства представляет собой минимальное приложение Hello world App Engine,
с одной нестандартной особенностью: вместо "Hello world" отображается
"Привет адрес электронной почты пользователя ", где
адрес электронной почты пользователя является аутентифицированным
адрес электронной почты пользователя.

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

  • X-Goog-Authenticated-User-Email : адрес электронной почты пользователя идентифицирует их.Не храните личную информацию, если ваше приложение может этого избежать. Это приложение не
    хранить любые данные; он просто повторяет его пользователю.

  • X-Goog-Authenticated-User-Id : этот идентификатор пользователя, присвоенный Google, не
    показывает информацию о пользователе, но позволяет приложению знать
    что вошедший в систему пользователь - это тот же пользователь, которого видели ранее.

  • X-Goog-Iap-Jwt-Assertion : вы можете настроить приложения Google Cloud
    принимать веб-запросы от других облачных приложений, минуя
    IAP, в дополнение к веб-запросам в Интернете.Если приложение такое
    настроен, такие запросы могут иметь поддельные заголовки.
    Вместо использования любого из ранее упомянутых текстовых заголовков вы
    может использовать и проверить этот криптографически подписанный заголовок, чтобы проверить, что информация
    был предоставлен Google. И адрес электронной почты пользователя, и постоянный
    ID пользователя доступны как часть этого подписанного заголовка.

Если вы уверены, что приложение настроено так, что только Интернет
веб-запросы могут достичь его, и что никто не может отключить IAP
сервис для приложения, то получение уникального идентификатора пользователя занимает всего одну строку
кода:

  $ userId = getallheaders () ['X-Goog-Authenticated-User-Id'] ?? ноль;
  

Примечание: getallheaders
функция доступна только для NGINX в PHP 7.3 или новее.

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

Создайте исходный код

  1. С помощью текстового редактора создайте файл с именем index.php и вставьте
    в нем следующий код:

    Это индекс .php подробно объясняется в
    Понимание кода
    раздел далее в этом руководстве.

  2. Создайте еще один файл с именем composer.json и вставьте следующий
    в него:

    В файле composer.json перечислены все библиотеки PHP, необходимые вашему приложению.
    App Engine для загрузки:

  3. Создайте файл с именем app.yaml и поместите в него следующий текст:

    Приложение .yaml сообщает App Engine, в какой языковой среде используется ваш код.
    требует.

Понимание кода

В этом разделе объясняется, как работает код из index.php . Если ты просто хочешь бежать
приложение, вы можете перейти к
Разверните приложение
раздел.

Следующий код находится в файле index.php . Когда HTTP GET запрос на
домашняя страница
полученный приложением, вызывается корпус переключателя для /:

Оператор switch получает значение заголовка утверждения JWT, которое IAP
добавляется из входящего запроса и вызывает функцию для проверки этого
криптографически подписанное значение.Первое возвращенное значение (электронная почта) затем используется в
минимальная веб-страница, которую он создает и возвращает.

Функция validate_assertion использует библиотеку google / auth для проверки того, что
утверждение правильно подписано, и для извлечения информации о полезной нагрузке из
утверждение. Если утверждение не может быть декодировано, функция выдает
исключение. В случае успеха функция возвращает электронную почту аутентифицированного пользователя.
адрес и постоянный уникальный идентификатор пользователя.

Проверка утверждения JWT требует знания сертификатов открытых ключей
субъект, подписавший утверждение (в данном случае Google), и аудитория
утверждение предназначено для. Для приложения App Engine аудитория
строка с идентификационной информацией проекта Google Cloud.
Эта функция получает
эти сертификаты и строка аудитории из предшествующих ей функций.

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

Служба метаданных App Engine (и аналогичные службы метаданных для других
Сервисы облачных вычислений Google) выглядит как веб-сайт и запрашивается
стандартные веб-запросы. Однако на самом деле это не внешний сайт, а
внутренняя функция, которая возвращает запрошенную информацию о запущенном
app, поэтому можно безопасно использовать http вместо запросов https .
Он используется для получения текущих идентификаторов Google Cloud, необходимых для определения
Целевая аудитория утверждения JWT.

Развертывание приложения

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

  1. В окне терминала перейдите в каталог, содержащий файл app.yaml ,
    и разверните приложение в App Engine:

      развертывание приложения gcloud
      
  2. При появлении запроса выберите ближайший регион.

  3. Когда вас спросят, хотите ли вы продолжить операцию развертывания, введите Y .

    Через несколько минут ваше приложение появится в Интернете.

  4. Посмотреть приложение:

      просмотр приложений gcloud
      

    В выводе скопируйте URL-адрес веб-сайта , веб-адрес
    для приложения.

  5. В окне браузера вставьте URL-адрес веб-сайта , чтобы открыть
    приложение.

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

Включить IAP

Теперь, когда существует экземпляр App Engine, вы можете защитить его с помощью
ИАП:

  1. В консоли Google Cloud перейдите на страницу Identity-Aware Proxy .

    Перейти на страницу Identity-Aware Proxy

  2. Поскольку вы впервые включили опцию аутентификации для
    этого проекта вы увидите сообщение о том, что вам необходимо настроить свое согласие OAuth
    экран, прежде чем вы сможете использовать IAP.

    Щелкните Настройка экрана согласия .

  3. На вкладке OAuth Consent Screen страницы Credentials заполните
    следующие поля:

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

    • В поле Application name введите IAP Example .

    • В поле Support email введите свой адрес электронной почты.

    • В поле Авторизованный домен введите часть имени хоста приложения
      URL-адрес, например iap-example-999999.uc.r.appspot.com . Нажмите кнопку Enter
      после ввода имени хоста в поле.

    • В поле Ссылка на домашнюю страницу приложения введите URL-адрес вашего приложения, для
      например, https://iap-example-999999.uc.r.appspot.com/ .

    • В поле строки политики конфиденциальности приложения укажите тот же URL-адрес, что и для
      ссылка на домашнюю страницу в целях тестирования.

  4. Нажмите Сохранить . Когда будет предложено создать учетные данные, вы можете закрыть окно.

  5. В облачной консоли перейдите на страницу Identity-Aware Proxy .

    Перейти на страницу Identity-Aware Proxy

  6. Чтобы обновить страницу, щелкните
    Обновить . В
    На странице отображается список ресурсов, которые вы можете защитить.

  7. В столбце IAP щелкните, чтобы включить IAP для приложения.

  8. В браузере снова перейдите по адресу web-site-url .

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

Добавить авторизованных пользователей в приложение

  1. В облачной консоли перейдите на страницу Identity-Aware Proxy.

    Перейти на страницу Identity-Aware Proxy

  2. Установите флажок для приложения App Engine и нажмите
    Добавить участника .

  3. Введите allAuthenticatedUsers , а затем выберите
    Cloud IAP / IAP-Secured Web App User role.

  4. Нажмите Сохранить .

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

  • Любой адрес электронной почты Gmail или Google Workspace

  • Адрес электронной почты Группы Google

  • Доменное имя Google Workspace

Доступ к приложению

  1. В браузере перейдите по адресу URL-адрес веб-сайта .

  2. Чтобы обновить страницу, нажмите Обновить .

  3. На экране входа в систему войдите со своими учетными данными Google.

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

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

Концепции аутентификации

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

Опция Преимущества Недостатки
Аутентификация приложения
  • Приложение может работать на любой платформе, с подключением к Интернету или без него.
  • Пользователям не нужно использовать какие-либо другие службы для управления аутентификацией.
  • Приложение должно безопасно управлять учетными данными пользователей, защищать от разглашения
  • Приложение должно поддерживать данные сеанса для вошедших в систему пользователей
  • Приложение должно обеспечивать регистрацию пользователя, смену пароля, восстановление пароля.
OAuth3
  • Приложение может работать на любой платформе, подключенной к Интернету, включая
    рабочее место разработчика
  • Приложение не требует регистрации пользователя, смены пароля или пароля.
    функции восстановления.
  • Риск раскрытия информации о пользователе делегирован другой службе
  • Новые меры безопасности при входе в систему вне приложения
  • Пользователи должны зарегистрироваться в службе идентификации.
  • Приложение должно поддерживать данные сеанса для вошедших в систему пользователей
ИАП
  • Приложению не нужен код для управления пользователями,
    аутентификация или состояние сеанса
  • В приложении нет учетных данных пользователя, которые могут быть взломаны
  • Приложение может работать только на платформах, поддерживаемых сервисом.В частности, некоторые сервисы Google Cloud, которые
    поддержка IAP, например App Engine.

Аутентификация, управляемая приложением

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

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

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

Внешняя аутентификация с помощью OAuth3

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

На следующей схеме показана внешняя аутентификация с помощью OAuth3.
метод.

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

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

Прокси-сервер с идентификацией

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

Обработка запроса показана на следующей диаграмме.

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

Приложению больше не требуется обрабатывать учетную запись пользователя или сеанс.
Информация. Любая операция, которой необходимо знать уникальный идентификатор для
пользователь может получить это непосредственно из каждого входящего веб-запроса. Однако это может
использоваться только для вычислительных служб, поддерживающих IAP, например
как App Engine и
балансировщики нагрузки. Вы не можете использовать IAP на локальной машине разработки.

Изучение HTTP-запроса в синтаксисе редактора

Чтобы составить HTTP-запрос в редакторе кода PhpStorm, используйте следующий общий синтаксис:

Метод Request-URI HTTP-Version
Поле заголовка: значение заголовка

Тело запроса

HTTP-запрос в формате Editor предоставляет дополнительные возможности, как показано в следующих примерах.Подробнее о работе с HTTP-запросами см. HTTP-клиент в редакторе кода PhpStorm.

  • В запросе начните любую строку с // или # , чтобы сделать ее строкой комментария.

    // Базовый запрос
    ПОЛУЧИТЬ http://example.com/a/

Использовать краткую форму для запросов GET

  • Для запросов GET вы можете опустить метод запроса и указать только URI.

    // Базовый запрос
    http: // пример.com / a /

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

  1. Отметьте конец запроса, введя разделитель ### под ним.

    // Базовый запрос
    http://example.com/a/

    ###

  2. Составьте еще один запрос ниже разделителя.

    // Базовый запрос
    http://example.com/a/

    ###

    // Второй запрос с использованием метода GET
    http: // пример.com: 8080 / api / html / get? id = 123 & value = content

Разбивайте длинные запросы на несколько строк

Доступ к веб-службе с аутентификацией

  • В зависимости от веб-службы, к которой вы обращаетесь, укажите основной или дайджест-заголовок авторизации.

    // Базовая аутентификация
    ПОЛУЧИТЬ http://example.com
    Авторизация: Базовый пароль от имени пользователя

    ###

    // Дайджест аутентификации
    ПОЛУЧИТЬ http: // example.ком
    Авторизация: дайджест логина и пароля

Подобно другим элементам HTTP-запроса, предоставленное имя пользователя и пароль можно параметризовать с помощью переменных среды.

Предоставьте тело сообщения запроса

Внутри запроса добавьте к телу запроса пустую строку и выполните одно из следующих действий:

  • Введите тело запроса на месте:

    // Тело запроса предоставляется на месте
    POST http: // example.ком: 8080 / api / html / post HTTP / 1.1
    Content-Type: application / json Cookie: key = first-value

    {"ключ": "значение", "список": [1, 2, 3]}

    Если вы установите значение поля заголовка Content-Type на один из языков, поддерживаемых PhpStorm, то соответствующий языковой фрагмент будет автоматически вставлен в тело сообщения HTTP-запроса. Если Content-Type не указан, вы можете вставить языковой фрагмент вручную. Для получения дополнительной информации см. Языковые инъекции.

  • Чтобы прочитать тело запроса из файла, введите символ <, за которым следует путь к файлу.

    // Тело запроса читается из файла
    POST http://example.com:8080/api/html/post
    Тип содержимого: приложение / json

    <./input.json

Использовать тип содержимого multipart / form-data

  • Установите для Content-Type запроса значение multipart / form-data.Чтобы отправить файл как часть сообщения multipart / form-data, включите параметр filename в заголовок Content-Disposition.

    POST http://example.com/api/upload HTTP / 1.1
    Тип содержимого: multipart / form-data; граница = граница

    - граница
    Content-Disposition: данные формы; name = "первый"; filename = "input.txt"

    // Файл 'input.txt' будет загружен
    <./input.txt - граница Content-Disposition: данные формы; name = "второй"; filename = "ввод-секунда.текст" // Будет создан и загружен временный файл input-second.txt с содержимым Text Текст - граница Content-Disposition: данные формы; name = "третий"; // Содержимое файла 'input.txt' будет отправлено в виде обычного текста. <./input.txt --boundary--

    Чтобы ускорить создание запроса multipart / form-data, используйте шаблон mptr live.

Включение или отключение следующих перенаправлений

В зависимости от веб-службы, к которой вы обращаетесь, вы можете захотеть, чтобы HTTP-запросы следовали перенаправлениям или нет.Когда выполняется перенаправление, возвращается ответ перенаправленной страницы; в противном случае возвращается фактический заголовок ответа перенаправления (например, 301 или 302).

  • Перед запросом добавьте строку комментария с тегом @ no-redirect .

    // @ без перенаправления
    example.com/status/301

Включение или отключение сохранения запросов в историю запросов

При необходимости вы можете запретить сохранение запроса в истории запросов.Это может быть полезно, если запрос содержит конфиденциальные данные, и вы не хотите регистрировать его.

  • Перед запросом добавьте строку комментария с тегом @ no-log .

    // @ без журнала
    ПОЛУЧИТЬ example.com/api

Включение или отключение сохранения полученных файлов cookie в банке файлов cookie

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

  • Перед запросом добавьте строку комментария с тегом @ no-cookie-jar .

    // @ no-cookie-jar
    ПОЛУЧИТЬ example.com/api

Использовать переменные

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

Укажите переменную внутри запроса.

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

Переменные среды

Переменные среды позволяют хранить набор определений среды внутри вашего проекта. Например, вы можете создать и использовать переменную {{host}} вместо того, чтобы явно указывать имя хоста в вашем запросе.Когда вы выполняете запрос, вы можете выбирать между определенными средами и, таким образом, отправлять его на конкретный хост:

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

Определить переменные среды

Переменные среды определены в файлах среды.

  1. В верхней части панели редактора запроса щелкните ссылку «Добавить файл среды».

  2. Выберите нужный тип среды во всплывающем меню.

    В зависимости от вашего выбора PhpStorm создаст внутри проекта следующие файлы:

    • При выборе Regular будет создан файл http-client.env.json. Этот файл может содержать общие переменные, такие как имя хоста, порт или параметры запроса, и предназначен для распространения вместе с вашим проектом.

    • При выборе «Частный» будет создан http-client.private.env.json файл. Этот файл может содержать пароли, токены, сертификаты и другую конфиденциальную информацию. По умолчанию он добавляется в список файлов, игнорируемых VCS. Значения переменных, указанные в файле http-client.private.env.json, имеют приоритет над значениями в обычном файле среды.

    При необходимости вы можете создать эти файлы вручную.

  3. Заполните созданные файлы необходимыми переменными.

    Следующий пример http-client.Файл среды env.json определяет две среды: разработку и производство. Дополнительный файл http-client.private.env.json содержит конфиденциальные данные авторизации.

    {
    "разработка": {
    "host": "localhost",
    "id-value": 12345,
    "имя пользователя": "",
    "пароль": "",
    "my-var": "my-dev-value"
    },

    "производство": {
    "хост": "пример.com ",
    "id-value": 6789,
    "имя пользователя": "",
    "пароль": "",
    "my-var": "my-prod-value"
    }
    }

    {
    "разработка": {
    "имя пользователя": "пользователь-разработчик",
    "пароль": "dev-пароль"
    },

    "производство": {
    "имя пользователя": "пользователь",
    "пароль": "пароль"
    }
    }

    Пример HTTP-запроса выглядит следующим образом:

    ПОЛУЧИТЬ http: // {{host}} / api / json / get? Id = {{id-value}}
    Авторизация: базовая {{username}} {{password}}
    Тип содержимого: приложение / json

    {
    "ключ": "{{my-var}}"
    }

    Когда вы выполняете вышеуказанный запрос, PhpStorm позволяет вам выбрать желаемую среду выполнения:

    В зависимости от вашего выбора результирующий запрос будет одним из следующих:

    ПОЛУЧИТЬ http: // localhost / api / json / get? Id = 12345
    Авторизация: базовый пароль разработчика-разработчика
    Тип содержимого: приложение / json

    {
    "ключ": "мое-дев-значение"
    }

    ПОЛУЧИТЬ http: // example.com / api / json / get? id = 6789
    Авторизация: Базовый пароль пользователя
    Тип содержимого: приложение / json

    {
    "ключ": "мое значение продукта"
    }

Если переменная не разрешена при выполнении запроса, PhpStorm отображает уведомление, позволяющее быстро создать, обновить или выбрать другую среду выполнения.

Динамические переменные

Динамические переменные генерируют значение каждый раз, когда вы запускаете запрос:

  • $ uuid : генерирует универсальный уникальный идентификатор (UUID-v4)

  • $ timestamp : генерирует текущий UNIX timestamp

  • $ randomInt : генерирует случайное целое число от 0 до 1000.

Например:

ПОЛУЧИТЬ http: // localhost / api / get? Id = {{$ uuid}}

Последнее изменение: 19 мая 2021 г.

WP JSON Basic Auth с FastCGI

Эта статья относится к реализации MetaLocator.

JSON API - отличное дополнение к WordPress. Мы обнаружили, что плагин Basic Auth некорректно работает на хостах, на которых работает PHP с FastCGI. Внимание : Неправильные изменения на вашем сайте.htaccess может привести к прекращению работы вашего веб-сайта. Обязательно выполняйте эти инструкции с помощью своего веб-мастера.

Исправление состоит из двух шагов:

Шаг 1

Обновите раздел mod_rewrite вашего файла .htaccess, включив в него следующие директивы:

   
#METALOCATOR: Эта строка добавлена, чтобы разрешить базовую аутентификацию в FastCGI
SetEnvIf Авторизация. + HTTP_AUTHORIZATION = $ 0

#METALOCATOR: включить механизм перезаписи.wp-json /.* - [E = HTTP_AUTHORIZATION:% {HTTP: Authorization}, L]

Эти строки должны быть помещены в любой существующий блок вместо добавления новый. Обычные установки WordPress уже включают такой блок , поэтому полный пример, интегрированный с предоставленным WordPress .htaccess, может выглядеть так:

  #BEGIN WordPress 

#METALOCATOR: Это добавлена ​​строка, разрешающая базовую аутентификацию при авторизации FastCGI
SetEnvIf.wp-json /.* - [E = HTTP_AUTHORIZATION:% {HTTP: Authorization}, L]

#END WordPress

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

Шаг 2

Установите плагин. Вы должны установить плагин, поместив файл basic-auth.php непосредственно в папку wp-content / plugins /. Его не следует устанавливать с помощью установщика плагинов WordPress, он должен быть добавлен через FTP или загружен иным образом.Затем плагин необходимо активировать обычным способом.

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

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