Аутентификация REST API

182

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

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

Нур
источник
4
Вероятно, вам следует поискать здесь "аутентификация REST". Это было затронуто во многих других вопросах.
Брайан Келли
10
Вкратце, позвольте клиенту отправлять имя пользователя и пароль с каждым запросом, используя HTTP Basic Auth (через SSL!), Или аутентифицироваться один раз, чтобы у клиента был аутентифицированный сеанс, который истечет после некоторого периода бездействия (или, как вы решите, переопределить обработка сеанса вашего веб-фреймворка). Затем указанный сеанс может быть сохранен в cookie или быть параметром, передаваемым с каждым запросом (например, JSESSIONID в Java).
Опять
@opyate с точки зрения безопасности, не рекомендуется обрабатывать сеанс с использованием файлов cookie в случае REST API, поскольку злоумышленники могут отправлять запросы без согласия пользователя. Лучше включить хэш сеанса или токен в заголовок HTTP (например, авторизацию).
s3v3n
1
@ s3v3n Поправьте меня, если я ошибаюсь, но и ваше, и мое предложение - это просто разные способы использования комбинации заголовок + локальное хранилище для достижения одного и того же. Это Authorizationзаголовок + например , заголовок браузера localStorage VS Cookie+ стандартное хранилище файлов cookie браузера.
Опять 01

Ответы:

72

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

  • Базовая аутентификация - использует кодировку Base64 для имени пользователя и пароля
  • Дайджест-аутентификация - хеширует имя пользователя и пароль перед их отправкой по сети.

OAuth - лучшее, что можно получить. Преимущества oAuth - это токен с возможностью отзыва или истечения срока действия. См. Следующее о том, как реализовать: Рабочая ссылка из комментариев: https://www.ida.liu.se/~TDP024/labs/hmacarticle.pdf

ankitjaininfo
источник
4
Пожалуйста, прочтите этот вопрос и ответ, предоставленный Лесом Хазелвудом (автором Apache Shiro).
justin.hughey 03
1
Полезная ссылка, как Twitter защищает свой REST API: Twitter REST API Security
WildDev
Поскольку это принятый ответ, я считаю важным упомянуть, что вы также можете использовать дайджест-аутентификацию. О различиях между базовой и дайджест-аутентификацией читайте здесь: stackoverflow.com/questions/9534602/…
Rayee Roded
116

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

Подумайте об этом - должно быть какое-то рукопожатие, которое сообщает вашему API «Создать форум», что этот текущий запрос исходит от аутентифицированного пользователя. Поскольку API-интерфейсы REST обычно не имеют состояния, состояние должно где-то сохраняться . Ваш клиент, использующий REST API, отвечает за поддержание этого состояния. Обычно это в форме некоторого токена, который передается с момента входа пользователя в систему. Если токен в порядке, ваш запрос верен.

Проверьте, как Amazon AWS выполняет аутентификацию. Это прекрасный пример «перекладывания денег» с одного API на другой.

* Я подумал добавить практический ответ на свой предыдущий ответ. Попробуйте Apache Shiro (или любую библиотеку аутентификации / авторизации). Итог, старайтесь избегать нестандартного кодирования. После того, как вы интегрировали свою любимую библиотеку (я использую Apache Shiro, кстати), вы можете сделать следующее:

  1. Создайте API входа / выхода, например: /api/v1/loginиapi/v1/logout
  2. В этих API входа и выхода выполните аутентификацию в своем хранилище пользователей.
  3. Результатом является токен (обычно JSESSIONID), который отправляется обратно клиенту (веб, мобильный, что угодно).
  4. С этого момента все последующие вызовы, сделанные вашим клиентом, будут включать этот токен
  5. Допустим, ваш следующий вызов сделан в API с именем /api/v1/findUser
  6. Первым делом этот код API проверит токен («аутентифицирован ли этот пользователь?»)
  7. Если ответ возвращается как НЕТ, вы возвращаете клиенту статус HTTP 401. Позвольте им справиться с этим.
  8. Если ответ ДА, то приступайте к возврату запрошенного пользователя

Вот и все. Надеюсь это поможет.

Kingz
источник
Итак, то, что вы описываете, по сути, является файлом cookie сеанса, верно?
LordOfThePigs
да, но сеанс "поддерживается" в 2 разных местах. Один на сервере API, другой в браузере. Ответ JSON (или любой другой) на сообщение браузера об успешном входе в систему должен передавать идентификатор сеанса на сервере API обратно в браузер. Эти сеансы независимо управляются соответствующими агентами.
Kingz
11
Я считаю, что Кингз пытался внушить идею о том, что механизм поддержания сеанса намеренно расплывчатый. Файл cookie сеанса - это лишь одна из реализаций этого механизма.
justin.hughey 03
2
@Kingz, как насчет безопасности в этом решении, например, если какой-нибудь хакер обнюхает ссылку с session_id и начнет отправлять запросы, контент которых правильный session_id? Мы можем решить эту проблему, добавив ssl к подключению к серверу, но как насчет клиентов?
Ахмад Самило
1
как предотвратить захват сеанса в случае привлечения человека посередине?
m0z4rt 01
38
  1. Используйте HTTP Basic Auth для аутентификации клиентов, но обрабатывайте имя пользователя и пароль только как временный токен сеанса .

    Токен сеанса - это просто заголовок, прикрепленный к каждому HTTP-запросу, например: Authorization: Basic Ym9ic2Vzc2lvbjE6czNjcmV0

    строка Ym9ic2Vzc2lvbjE6czNjcmV0 выше - это просто строка «bobsession1: s3cret» (которая является именем пользователя / паролем), закодированная в Base64.

  2. Чтобы получить временный токен сеанса, указанный выше, предоставьте функцию API (например:), http://mycompany.com/apiv1/loginкоторая принимает в качестве входных данных имя главного пользователя и главный пароль, создает временное имя пользователя / пароль HTTP Basic Auth на стороне сервера и возвращает токен (например: Ym9ic2Vzc2lvbjE6czNjcmV0). Это имя пользователя / пароль должны быть временными, срок их действия должен истечь примерно через 20 минут.

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

Если вы используете Java, библиотека Spring Security обеспечивает хорошую поддержку для реализации вышеуказанного метода.

Gerrytan
источник
1
Почему он должен истечь через 20 минут? что, если это такой веб-сайт, как facebook, где логин будет до тех пор, пока пользователь не выйдет из системы?
Dejell
1
@dejel Я предположил, что "сеанс" носит временный характер. Обычно срок его действия истекает, если пользователь
бездействует
Для чего нужен Base64? Вы можете просто вернуть временный пароль. В обоих случаях действительно важно, чтобы этот временный пароль был надежным. Проверьте security.stackexchange.com/a/19686/72945
e18r
7

Я думаю, что лучше всего использовать OAuth2. Погуглите, и вы найдете много полезных сообщений, которые помогут вам его настроить.

Это упростит разработку клиентских приложений для вашего API из веб-приложения или мобильного приложения.

Надеюсь, это поможет тебе.

Пауло Энрике
источник
2
Прочтите этот вопрос и ответ Леса Хазелвуда (автора Apache Shiro).
justin.hughey 03
0

Я использую аутентификацию JWT. Прекрасно работает в моем приложении.

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

Этот токен должен быть отправлен любому другому методу в моем веб-API в заголовке запроса.

Это довольно легко реализовать и очень легко протестировать.

Артур Медейрос
источник