Я все еще пытаюсь найти лучшее решение для защиты API REST, потому что количество мобильных приложений и API растет с каждым днем.
Я пробовал разные способы аутентификации, но все еще есть некоторые недоразумения, поэтому мне нужен совет кого-то более опытного.
Позвольте мне рассказать, как я понимаю все эти вещи. Если я что-то неправильно понимаю, пожалуйста, дайте мне знать.
Поскольку REST API не имеет состояния, а также WEB в целом, нам необходимо отправлять некоторые данные аутентификации в каждом запросе (куки, токен ....). Я знаю три широко используемых механизма аутентификации пользователя
Токен с HTTPS. Я использовал этот подход много раз, он достаточно хорош с HTTPS. Если пользователь предоставит правильный пароль и логин, он получит токен в ответ и будет использовать его для дальнейших запросов. Токен генерируется сервером и сохраняется, например, в отдельной таблице или там же, где хранится информация о пользователе. Таким образом, для каждого сервера запросов проверяется, есть ли у пользователя токен, и он такой же, как в базе данных. Все довольно просто.
JWT Token. Этот токен является информативным, он содержит всю необходимую информацию о самом токене, пользователь не может изменить, например, дату истечения срока действия или любую другую заявку, поскольку этот токен генерируется (подписывается) сервером с секретным ключевым словом. Это тоже понятно. Но одна большая проблема, лично для меня, как аннулировать токен.
OAuth 2. Я не понимаю, почему этот подход следует использовать, когда связь устанавливается непосредственно между сервером и клиентом. Насколько я понимаю, OAuth-сервер используется для выдачи токена с ограниченной областью действия, чтобы другие приложения могли получать доступ к пользовательской информации без сохранения пароля и логина. Это отличное решение для социальных сетей, когда пользователь хочет зарегистрироваться на какой-либо странице, сервер может запросить разрешения на получение информации о пользователе, например, из твиттера или Facebook, и заполнить поля регистрации данными пользователя и так далее.
Рассмотрим мобильный клиент для интернет-магазина.
Первый вопрос: я должен предпочесть JWT токену первого типа? Поскольку мне нужно войти / выйти из системы на мобильном клиенте, мне нужно где-то хранить токен или, в случае JWT, токен должен быть аннулирован при выходе из системы. Для аннулирования токена используются разные подходы. Одним из них является создание списка недействительных токенов (черный список). Хм. Таблица / файл будет иметь гораздо больший размер, чем если бы токен хранился в таблице и был связан с пользователем и был удален при выходе из системы.
Так каковы преимущества токена JWT?
Второй вопрос о OAuth, должен ли я использовать его в случае прямой связи с моим сервером? Какова цель еще одного слоя между клиентом и сервером только для выдачи токена, но связь будет осуществляться не с oauth-сервером, а с главным сервером. Как я понимаю, сервер OAuth отвечает только за предоставление сторонним приложениям разрешений (токенов) для доступа к личной информации пользователя. Но мое мобильное клиентское приложение не стороннее.
Ответы:
Рассмотрим первый случай. Каждый клиент получает случайный идентификатор, который длится на протяжении сеанса - который может быть несколько дней, если хотите. Затем вы сохраняете информацию, относящуюся к этому сеансу где-то на стороне сервера. Это может быть в файле или базе данных. Предположим, вы передаете идентификатор через cookie, но можете использовать URL-адрес или заголовок HTTP.
Идентификаторы сессии / файлы cookie
Плюсы:
Минусы:
JSON Web Tokens (JWT)
Во втором случае данные хранятся в JWT, который передается, а не на сервере.
Плюсы:
Минусы:
На стороне сервера необходим код для генерации, проверки и чтения JWT. Это не сложно, но есть некоторая кривая обучения, и от этого зависит безопасность.
Любой, кто получит копию ключа подписи, может создать JWT. Вы можете не знать, когда это произойдет.
Была (есть?) Ошибка в некоторых библиотеках, которые принимали любой JWT, подписанный с помощью алгоритма «none», чтобы любой мог создать JWT, которому сервер доверял бы.
Для того, чтобы отозвать JWT до истечения срока его действия, вам нужно использовать список отзыва. Это возвращает вас к проблемам хранения на стороне сервера, которые вы пытались избежать.
OAuth
Часто OAuth используется для аутентификации (т. Е. Идентификации), но его можно использовать для обмена другими данными, такими как список контента, который пользователь приобрел и имеет право на скачивание. Он также может быть использован для предоставления доступа для записи данных, хранящихся третьей стороной. Вы можете использовать OAuth для аутентификации пользователей, а затем использовать серверное хранилище или JWT для данных сеанса.
Плюсы:
Минусы:
Разнообразный
источник
Спросите себя, почему вам нужно аннулировать оригинальный токен.
Пользователь входит в систему, генерируется токен и приложение отключается.
Пользователь нажимает кнопку выхода, генерируется новый токен, который заменяет оригинальный токен. Еще раз, все хорошо.
Вы, кажется, беспокоитесь о случае, когда оба жетона торчат. Что делать, если пользователь выходит из системы, а затем каким-то образом делает запрос, используя зарегистрированный токен. Насколько реалистичен этот сценарий? Это просто проблема во время выхода из системы или есть много возможных сценариев, когда множественные токены могут быть проблемой?
Я сам не думаю, что стоит беспокоиться. Если кто-то перехватывает и декодирует ваши зашифрованные данные https, тогда у вас гораздо большие проблемы.
Вы можете дать себе дополнительную защиту, указав срок действия оригинального токена. Так что, если в итоге его украдут или что-то в этом роде, это будет хорошо только в течение короткого периода времени.
В противном случае, я думаю, вам понадобится информация о состоянии на сервере. Не помещайте в черный список токены, а помещайте в белый список подпись текущего токена.
источник
Вы можете справиться с упомянутыми выше проблемами JWT, сохранив значение соли вместе с пользователем и используя соль как часть токена для пользователя. Затем, когда вам нужно аннулировать токен, просто измените соль.
Я знаю, что это было пару лет, но сейчас я бы поступил иначе. Думаю, я бы обеспечил относительно короткое время жизни токенов доступа, скажем, час. Я также обязательно использовал бы токены обновления с состоянием на сервере, а затем, когда мне захотелось завершить чей-то сеанс, я бы отозвал токен обновления, удалив его с сервера. Затем через час пользователь выйдет из системы и должен будет снова войти в систему, чтобы восстановить доступ.
источник