В Интернете много информации об OAuth 2, его различных типах потоков и о том, где и как их использовать. Я считаю, что большинство этих ресурсов обсуждают аутентификацию пользователя для приложения, но я изо всех сил пытаюсь понять, какой будет наилучший / правильный подход при использовании сторонних API (т.е. когда наш собственный API является «посредником» между пользователем и его пользователями). данные в стороннем API).
С помощью примера сценария и некоторых диаграмм, я был бы очень признателен за совет / мнение о том, как правильно реализовать интеграцию со сторонними API, и каковы плюсы и минусы каждого подхода.
Начальная точка
В качестве отправной точки предположим, что у нас есть веб-приложение, структурированное следующим образом:
- Frontend - SPA (угловой), размещенный на AWS S3 + Cloudfront
- Backend - узел, работающий как лямбда-функции AWS без сохранения состояния с AWS API Gateway
- Auth0 для обработки авторизации / входа и т. Д. Интерфейс использует неявный поток OAuth2 для получения access_tokens, которые хранятся в локальном хранилище и включаются в качестве заголовка во все запросы к бэкэнду.
- Потенциально также собственные мобильные приложения, использующие тот же API бэкэнда.
Цель
Теперь предположим, что мы хотим добавить интеграцию с Google Sheets. Новая функция позволит пользователям использовать свои собственные Листы Google (т.е. хранящиеся в собственной учетной записи Google) в качестве источника данных, а приложение будет иметь доступ к листу для чтения и записи. В будущем возможны другие интеграции, поэтому я предполагаю, что для других API потребуется аналогичный процесс.
Постановка проблемы
В дополнение к существующему процессу OAuth (который позволяет пользователям входить в интерфейс MyApp и взаимодействовать с MyApp API), необходим дополнительный процесс OAuth, позволяющий пользователям подключать MyApp к третьей стороне. API Google Sheets .
В документации есть два примера быстрого запуска, но ни один из них не совсем соответствует моим потребностям:
Браузер - https://developers.google.com/sheets/api/quickstart/js
Node.js (консольное приложение) - https://developers.google.com/sheets/api/quickstart/nodejs
Данные от стороннего (Google) API являются одной из потенциально нескольких точек интеграции, поэтому интуитивно кажется более логичным (и более безопасным), что все взаимодействие с API Google Sheets должно происходить в MyApp API
, и не на стороне клиента / клиента. MyApp API
будет извлекать данные, обрабатывать / манипулировать / форматировать их каким-либо образом, а затем представлять их для отображения в веб-интерфейсе или мобильных приложениях.
Нам требуется доступ к собственным данным каждого пользователя, поэтому поток Client Credentials
не подходит. Я сосредоточен на рабочих процессах Implicit
или Authorization Grant
.
Важное примечание: хитрость, похоже, связана с тем фактом, что MyApp API
не имеет состояния, поэтому не существует долгоживущего сеанса для хранения токенов. Исходя из этого, кажется, что токены необходимо хранить либо во внешнем интерфейсе (например, в локальном хранилище / файлах cookie и т. Д.), Либо в базе данных бэкэнда.
Ниже моя интерпретация двух возможных подходов. Буду признателен за мысли / исправления.
Вариант 1: неявный поток - токены, хранящиеся в FE, переданные в BE, которые затем отправляют запросы в Google
Плюсы:
- Разрешает доступ к собственным данным пользователя
- Более простой поток,
access_token
извлекается немедленно, без необходимости code
step
- Меньше шагов для выполнения между начальным входом в систему и фактическим получением данных
- Нет необходимости в серверной базе данных, может пересылать токен с каждым запросом
Минусы:
- Фронтенд (браузер) имеет доступ к Google access_token, который кажется ненужным и является потенциальной проблемой безопасности
- Кажется странным процесс передачи access_token из FE в BE, просто чтобы позволить BE затем использовать этот токен для выполнения другого запроса
- Я не уверен, как мы будем обновлять / обновлять токены, так как я понимаю, что хранение refresh_tokens на клиенте - плохая практика. Было бы не очень удобно, если бы пользователю приходилось часто входить в систему для повторного подключения своей учетной записи
Вариант 2. Поток кодов авторизации - все общение с Google через BE, токены хранятся в базе данных BE
Плюсы:
- Разрешает доступ к собственным данным пользователя
- За исключением страницы запроса кода / согласия, вся связь с Google реализована бэкэндом, поэтому токены недоступны на клиенте
- Секрет клиента можно использовать из BE
Минусы:
- Более сложный поток, требующий дополнительных шагов
- Учитывая, что BE не имеет состояния, неясно, как лучше хранить токены. Похоже, что это потребовало бы их хранения в базе данных, что является дополнительным осложнением и, похоже, имело бы последствия для безопасности - как бы вы должным образом обезопасили / зашифровали access_token / refresh_tokens в указанной базе данных?
Заключение
Учитывая, что обработка данных должна выполняться на бэкэнде, вариант 2 кажется несколько более подходящим, поскольку чувствительные токены могут быть скрыты от приложения внешнего интерфейса, а несколько клиентов (веб-интерфейс, мобильные приложения) имеют меньше обязательств участвовать в процесс за исключением первоначального входа / согласия пользователя. Однако я не уверен, является ли хорошей идеей иметь базу данных, полную пользовательских токенов аутентификации, или как я мог бы правильно защитить эту базу данных.