Подтвердить что ты не робот

Как использовать токен доступа пользователя Facebook на стороне сервера?

Введение

Я разрабатываю несколько веб-сервисов и несколько клиентов (веб-приложение, мобильное устройство и т.д.), которые будут взаимодействовать с указанными службами через 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 (за исключением серверов веб-клиентов).

Workflow diagram

Вопросы

  • Прежде всего, существуют ли какие-либо вопиющие пробелы/ямы с описанным подходом на основе моего предисловия и требований?

  • Выполняет исходящий запрос в Facebook для проверки токена доступа (шаги 6-8 выше) на запрос клиента требуется/рекомендуется?

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

    Например, возможные мысли:

    • Хешируйте пару токена + userId после завершения первой проверки и сохраните ее в распределенном кеше (доступном для всех веб-серверов) с истечением срока, равным токенам доступа. По последующим запросам клиентов хэш-парад доступа + userId и проверяет его существование в кеше. Если есть, то запрос разрешен. В противном случае обратитесь к графическому API-интерфейсу Facebook, чтобы подтвердить токен доступа. Я предполагаю, что эта стратегия может быть осуществимой, если Im использует HTTPS (что я буду). Однако как производительность сравнивается?

    • Принятый ответ в qaru.site/info/78458/... рекомендует создать маркер пользовательского доступа после завершения первой проверки токена пользователя Facebook. Пользовательский токен затем будет отправлен клиенту для последующих запросов. Мне кажется, что это сложнее, чем вышеупомянутое решение. Это потребует внедрения моего собственного поставщика удостоверений (чего я хочу избежать, потому что я хочу использовать внешние поставщики удостоверений в первую очередь...). Есть ли какая-то заслуга в этом предположении?

  • Является ли поле signedRequest присутствующим в ответе на шаге № 3 выше (упоминается здесь), что эквивалентно параметру подписанного запроса здесь в потоке входа в холдинг для игр?

    Кажется, что они намекают как эквивалент, поскольку прежние ссылки на последние в документации. Тем не менее, Im удивил, что стратегия проверки, упомянутая на странице игр, не упоминается в "ручном построении потока входа page веб-документации.

  • Если ответ на # 3 есть "Да, может ли та же стратегия подтверждения идентификации для декодирования подписи и сравнения с тем, что ожидается на серверной стороне?

    Decode & compare from FB docs

    Мне интересно, можно ли это использовать вместо того, чтобы делать исходящий вызов API-интерфейса debug_token (шаг № 6 выше), чтобы подтвердить токен доступа, как рекомендовано здесь:

    debug_token graph API from FB docs

    Конечно, чтобы сделать сравнение на стороне сервера, подписанная часть запроса должна быть отправлена ​​вместе с запросом на сервер (шаг № 5 выше). В дополнение к выполнимости, не жертвуя безопасностью, Im задается вопросом, как производительность будет сравниваться с исходящим вызовом.

  • В то время как Im в нем, в каком сценарии/с какой целью, вы бы сохраняли токен доступа пользователя к базе данных, например? Я не вижу сценарий, где мне нужно будет это сделать, однако я могу кое-что игнорировать. Мне любопытно было некоторые распространенные сценарии, которые могли бы вызвать некоторые мысли.

Спасибо!

4b9b3361

Ответ 1

Из того, что вы описали, я предлагаю использовать входной поток на стороне сервера, как описано в

чтобы токен уже был на вашем сервере и не должен передаваться от клиента. Если вы используете нешифрованные соединения, это может быть угрозой безопасности (например, для атак типа "человек в середине" ).

Шагами будут следующие:

(1) Регистрация людей в

Вам нужно указать разрешение, которое вы хотите собрать от пользователей в параметре scope. Запрос может быть вызван только через обычную ссылку:

GET https://www.facebook.com/dialog/oauth?
    client_id={app-id}
   &redirect_uri={redirect-uri}
   &response_type=code
   &scope={permission_list}

См

(2) Подтвердите идентификатор

GET https://graph.facebook.com/oauth/access_token?
    client_id={app-id}
   &redirect_uri={redirect-uri}
   &client_secret={app-secret}
   &code={code-parameter}

(3) Проверьте маркер доступа

Вы можете проверить токен, как вы уже сказали в своем вопросе, через

GET /debug_token?input_token={token-to-inspect}
    &access_token={app-token-or-admin-token}

Это должно быть сделано только на стороне сервера, потому что в противном случае вы сделали бы токен доступа к приложениям видимым для конечных пользователей (не очень хорошая идея!).

См

(4) Расширение токена доступа

Как только вы получили (кратковременный) токен, вы можете сделать вызов для продления токена, как описано в

как показано ниже:

GET /oauth/access_token?grant_type=fb_exchange_token
    &client_id={app-id}
    &client_secret={app-secret}
    &fb_exchange_token={short-lived-token}

(5) Хранение токенов доступа

Что касается хранения токенов на сервере, FB предлагает сделать это:

(6) Обработка истекших токенов доступа

Поскольку FB не уведомляет вас об истечении срока действия токена (и если вы не сохраняете дату истечения срока действия и сравниваете это с текущей меткой времени перед выполнением вызова), возможно, что вы получаете сообщения об ошибках от FB, если токен получил недействительный (через 60 дней). Код ошибки будет 190:

{
  "error": {
    "message": "Error validating access token: Session has expired at unix 
                time SOME_TIME. The current unix time is SOME_TIME.", 
    "type": "OAuthException", 
    "code": 190
  }
}

См.

Если токен доступа становится недействительным, решение заключается в повторном входе пользователя в систему, после чего вы сможете снова вызвать вызовы API от их имени. Входной поток, используемый вашим приложением для новых пользователей, должен определить, какой метод вам нужно принять.