Введение
Я разрабатываю несколько веб-сервисов и несколько клиентов (веб-приложение, мобильное устройство и т.д.), которые будут взаимодействовать с указанными службами через HTTP (-ы). Мой текущий рабочий элемент - это разработка решения для проверки подлинности и авторизации для продукта. Я решил использовать внешние удостоверения личности, такие как Facebook, Google, Microsoft, Twitter и т.д. Для аутентификации.
Я пытаюсь решить проблему "когда запрос приходит на мой сервер, откуда я знаю, кто такой пользователь и как я могу быть уверен?". Еще вопросы ниже...
Требования
- Полагайтесь на внешние идентификаторы, чтобы указать, с кем я имею дело ( "userId" по сути это все, о чем я забочусь).
-
Система должна использовать аутентификацию на основе токенов (в отличие от файлов cookie, например, базового auth).
Я считаю, что это правильный выбор для масштабирования нескольких клиентов и серверов, обеспечивая свободную связь.
Workflow
Основываясь на моем чтении и понимании аутентификации на токенах, следующим я представляю, как я могу представить рабочий процесс. Теперь сосредоточьтесь на Facebook в веб-браузере. Мое предположение заключается в том, что другие внешние поставщики удостоверений должны иметь схожие возможности, хотя я еще не подтвердил их.
Заметьте, что с момента написания я основываю следующую версию Facebook для входа в систему 2.2.
- Клиент: Инициирует логин для Facebook с помощью JavaScript SDK
- Facebook: Пользователь аутентифицирует и утверждает разрешения приложений (например, для доступа к обычному пользователю)
- Facebook: Отправляет ответ клиенту, который содержит токены доступа пользователей, идентификатор и подписанный запрос
- Клиент: Сохраняет токен доступа пользователя в сеансе браузера (обрабатывается SDK удобно)
- Клиент: Выполняет запрос к моему веб-сервису для безопасного ресурса путем отправки по токену доступа пользователей в заголовок авторизации + идентификатор пользователя (в потенциальном заголовке потенциально)
- Сервер: Считывает токен доступа пользователя из заголовка запроса и инициирует проверку, отправив запрос в API-интерфейс debug_token, предоставленный Facebook.
- Facebook: Отвечает на сервер с информацией доступа к токенам пользователя (содержит appId и userId)
- Сервер: Завершает проверку токена, сравнивая appId с ожидаемым (известным самим) и userId тем, что было отправлено по запросу клиента.
- Сервер: Отвечает клиенту с запрошенным ресурсом (при условии счастливого пути авторизации)
Представьте, что шаги 5-9 повторяются для последующих запросов к серверу (в то время как токен доступа пользователей действителен - не истек, отменен со стороны FB, изменения в приложении и т.д.)
Здесь приведена диаграмма, которая поможет выполнить шаги. Пожалуйста, поймите, что эта система не - одностраничное приложение (SPA). Указанные веб-службы являются конечными точками API, которые обслуживают данные JSON для клиентов по существу; они не обслуживают HTML/JS/CSS (за исключением серверов веб-клиентов).
Вопросы
-
Прежде всего, существуют ли какие-либо вопиющие пробелы/ямы с описанным подходом на основе моего предисловия и требований?
-
Выполняет исходящий запрос в Facebook для проверки токена доступа (шаги 6-8 выше) на запрос клиента требуется/рекомендуется?
Я знаю, по крайней мере, я должен проверить токен доступа, поступающий из запроса клиента. Однако рекомендуемый подход для последующих проверок после первого неизвестен мне. Если есть типичные шаблоны, мне интересно узнать о них. Я понимаю, что они могут быть зависимыми от приложений на основе моих требований; однако, я просто не знаю, что искать. Я приложил должное внимание, когда у меня есть основная идея.
Например, возможные мысли:
-
Хешируйте пару токена + userId после завершения первой проверки и сохраните ее в распределенном кеше (доступном для всех веб-серверов) с истечением срока, равным токенам доступа. По последующим запросам клиентов хэш-парад доступа + userId и проверяет его существование в кеше. Если есть, то запрос разрешен. В противном случае обратитесь к графическому API-интерфейсу Facebook, чтобы подтвердить токен доступа. Я предполагаю, что эта стратегия может быть осуществимой, если Im использует HTTPS (что я буду). Однако как производительность сравнивается?
-
Принятый ответ в qaru.site/info/78458/... рекомендует создать маркер пользовательского доступа после завершения первой проверки токена пользователя Facebook. Пользовательский токен затем будет отправлен клиенту для последующих запросов. Мне кажется, что это сложнее, чем вышеупомянутое решение. Это потребует внедрения моего собственного поставщика удостоверений (чего я хочу избежать, потому что я хочу использовать внешние поставщики удостоверений в первую очередь...). Есть ли какая-то заслуга в этом предположении?
-
-
Является ли поле signedRequest присутствующим в ответе на шаге № 3 выше (упоминается здесь), что эквивалентно параметру подписанного запроса здесь в потоке входа в холдинг для игр?
Кажется, что они намекают как эквивалент, поскольку прежние ссылки на последние в документации. Тем не менее, Im удивил, что стратегия проверки, упомянутая на странице игр, не упоминается в "ручном построении потока входа page веб-документации.
-
Если ответ на # 3 есть "Да, может ли та же стратегия подтверждения идентификации для декодирования подписи и сравнения с тем, что ожидается на серверной стороне?
Мне интересно, можно ли это использовать вместо того, чтобы делать исходящий вызов API-интерфейса debug_token (шаг № 6 выше), чтобы подтвердить токен доступа, как рекомендовано здесь:
Конечно, чтобы сделать сравнение на стороне сервера, подписанная часть запроса должна быть отправлена вместе с запросом на сервер (шаг № 5 выше). В дополнение к выполнимости, не жертвуя безопасностью, Im задается вопросом, как производительность будет сравниваться с исходящим вызовом.
-
В то время как Im в нем, в каком сценарии/с какой целью, вы бы сохраняли токен доступа пользователя к базе данных, например? Я не вижу сценарий, где мне нужно будет это сделать, однако я могу кое-что игнорировать. Мне любопытно было некоторые распространенные сценарии, которые могли бы вызвать некоторые мысли.
Спасибо!