Аутентификация, авторизация и управление сессиями в традиционных веб-приложениях и API
======================================================================================

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

Однако в приложении на основе API эта информация не отправляется автоматически, поэтому при разработке API я должен сам проверить, поступает ли запрос, например, от аутентифицированного пользователя? Как это обычно делается?

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

Более того, в классических веб-приложениях после аутентификации и авторизации пользователя
(в основном путем поиска пары имя пользователя / пароль в базе данных), информация об авторизации и личности записывается в хранилище сессии. Хранилище сессий не обязательно должно быть на стороне сервера, как предполагает большинство ответов выше, оно также может храниться в cookie на стороне клиента, зашифрованным в большинстве случаев. Например, PHP CodeIgniter Framework делает это по умолчанию. Существует ряд механизмов для защиты сеанса на стороне клиента, и я не вижу такого способа хранения данных сеанса менее безопасным, чем хранение sessionId, который затем ищется в хранилище сеансов на стороне сервера. Кроме того, хранение клиентской части сеанса довольно удобно в распределенной среде, поскольку устраняет необходимость в разработке решения (или использовании уже существующего) для централизованного управления сеансами на стороне сервера.

Более того, аутентификация с простой парой пользователь-пароль не обязательно должна выполняться во всех случаях с помощью специального кода, который ищет соответствующую запись пользователя в базе данных. Есть, например[базовый протокол аутентификации](https://www.w3.org/Protocols/HTTP/1.0/draft-ietf-http-spec.html) , или же[дайджест-аутентификация](https://www.w3.org/Security/Implementation/DigestAuthFilter.html), На проприетарном программном обеспечении, таком как платформа Windows, есть также способы аутентификации пользователя, например,[ActiveDirectory](https://en.wikipedia.org/wiki/Active_Directory)

Предоставление пары имя пользователя / пароль не только способ аутентификации, если вы используете протокол HTTPS, вы также можете рассмотреть аутентификацию[используя цифровые сертификаты](https://www.techrepublic.com/article/secure-web-services-with-user-authentication-and-digital-certificates/1044829).

В конкретном случае использования при разработке веб-службы, которая использует SOAP в качестве протокола, также существует[WS-Security](https://en.wikipedia.org/wiki/WS-Security) расширение для протокола SOAP.

Учитывая все вышесказанное, я бы сказал, что ответы на следующий вопрос входят в процедуру принятия решения по выбору механизма авторизации / аутентификации для WebApi:

1) Какова целевая аудитория, является ли она общедоступной или только для зарегистрированных (платящих) участников?  

2) Это работает или * NIX, или платформа MS  

3) Какое количество пользователей ожидается  

4) Сколько имеет дело с API конфиденциальных данных (сильнее против слабых механизмов аутентификации)  

5) Есть ли какая-либо служба единого входа, которую вы могли бы использовать  

.. и многое другое

Надеюсь, что это немного прояснит ситуацию, так как в уравнении много переменных.



 то API должен иметь возможность извлекать / считывать файлы cookie из потока ответов сервера и сохранять их. Для автоматического добавления файлов cookie при подготовке объекта запроса для того же сервера / URL. Если он недоступен, идентификатор сессии не может быть получен.



 и причина в том, что все происходит автоматически. в стандартной среде это связано с тем, что файлы cookie предпочтительнее, чем распространение URL-адресов, для удобства пользователей. Тем не менее, браузер (клиентское программное обеспечение) управляет хранением и отправкой куки сессии вместе с каждым запросом.

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

Существует множество других механизмов аутентификации для API на основе HTTP, HTTP basic / digest для именования пары и, конечно, вездесущий o-auth, который разработан специально для этих вещей, если я не ошибаюсь. Файлы cookie не поддерживаются, cr, edentials являются частью каждого обмена (довольно точно).

Другая вещь, которую следует учитывать, - это то, что вы собираетесь делать с сеансом на сервере в API. Сеанс на веб-сайте предоставляет хранилище для текущего пользователя и, как правило, хранит небольшие объемы данных, чтобы снять нагрузку с БД со страницы на страницу. В контексте API это менее необходимо, поскольку вещи более или менее сохраняют состояние, говоря в общем, конечно; это действительно зависит от того, что делает сервис.



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

После создания сеанса вы можете сохранить на нем данные. Например, если вы хотите сохранить пользователя в журнале:

Теперь вы можете проверить, аутентифицирован ли пользователь или нет:

Если вы хотите, вы можете создать сеанс только для аутентифицированного пользователя:



Зависит от сервера и сервиса, которые могут быть[JSESSIONID](https://stackoverflow.com/questions/595872/under-what-conditions-is-a-jsessionid-created) параметр в вашем запросе GET / POST или что-то вроде[SAML](https://en.wikipedia.org/wiki/Security_Assertion_Markup_Language) в SOAP через HTTP в вашем запросе веб-службы.



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

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

Cookies

В типичном случае браузер-сервер; браузер управляет списком пар ключ / значение, которые называются куки, для каждого домена:

Cookies can be managed by the server (created/modified/deleted) using the `Set-Cookie` HTTP response header.
Cookies can be accessed by the server (read) by parsing the `Cookie` HTTP request header.

Языковые / фреймворки для веб-программирования предоставляют функции для работы с файлами cookie на более высоком уровне, например, PHP предоставляет[`setcookie`](https://php.net/manual/en/function.setcookie.php)/[`$_COOKIE`](http://www.php.net/manual/en/reserved.variables.cookies.php) писать / читать куки.

Sessions

Вернемся к сеансам. В типичном случае браузер-сервер (опять же) управление сеансами на стороне сервера использует преимущества управления cookie на стороне клиента.[Управление сессиями PHP](http://www.php.net/manual/en/ref.session.php) устанавливает cookie-файл идентификатора сеанса и использует его для идентификации последующих запросов.

Web applications API?

Теперь вернемся к вашему вопросу; поскольку вы несете ответственность за разработку и документирование API, реализация будет вашим решением. Вы в основном должны

give the client an identifier, be it via a `Set-Cookie` HTTP response header, inside the response body (XML/JSON auth response).
have a mechanism to maintain identifier/client association. for example a database table that associates identifier `00112233445566778899aabbccddeeff` with client/user #`1337`.
have the client resend the identifier sent to it at (1.) in all subsequent requests, be it in an HTTP `Cookie` request header, a `?sid=00112233445566778899aabbccddeeff` param(*).
lookup the received identifier, using the mechanism at (2.), check if a valid authentication, and is authorized to do requested operation, and then proceed with the operation on behalf on the auth'd user.

Конечно, вы можете опираться на существующую инфраструктуру, вы можете использовать управление сессиями PHP (которое позаботится о 1./2. И части 4. аутентификации) в вашем приложении и потребовать, чтобы реализация на стороне клиента выполняла управление файлами cookie. (это позаботится о 3.), а затем вы делаете всю остальную логику своего приложения на этом.

(*) У каждого подхода есть свои плюсы и минусы, например, использование параметра запроса GET проще в реализации, но может иметь последствия для безопасности, поскольку запросы GET регистрируются. Вы должны использовать https для критических (всех?) Приложений.