2015-04-16 2 views
23

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

У меня есть API, который нуждается в аутентификации. Я хочу, чтобы включить два случая использования:

  1. регистрации пользователя в интерфейсе с помощью oauth2 (грант пароля), и предоставляется маркер временного доступа. Этот токен используется для аутентификации пользователя. Поэтому пользовательский интерфейс, который сам использует API, может извлекать данные и отображать их.

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

В то же время, я не уверен, как это сделать. Я думаю, что внутри, как ключи API, так и токены доступа должны храниться в одной таблице, но ключи API не имеют времени истечения. Я прав?

Одна вещь, которую я не уверен, также является концепцией клиента. Похоже, что в спецификации клиент больше похож на внешнее приложение. Однако могу ли я использовать эту концепцию здесь?

Например, каждый «проект» на самом деле является другим клиентом (хотя клиент здесь - это одно и то же приложение, а не приложение, созданное сторонним разработчиком).

Поэтому, если пользователь A создает учетную запись в системе, клиент A будет автоматически создан с токеном доступа, привязанным к клиенту A, с долгоживущим токеном доступа (aka API key). Например, это можно использовать для выполнения вызовов API непосредственно на его код.

Затем, если пользователь A войдет в панель управления, будет создан токен доступа, но на этот раз без приложения, но привязанного к пользователю, с коротким сроком службы.

Звучит это здорово? Кто-нибудь уже реализовал такую ​​вещь?

Спасибо!

+1

Ключи API и токены доступа - это разные концепции, моделируйте их отдельно и храните их отдельно. –

+0

Да, но как вы справляетесь с тем, что я хочу получить доступ к API в однородном виде? Я не хочу иметь разные способы использования API. Независимо от того, использует ли мое веб-приложение его использование временного токена или клиента, использующего API непосредственно с его веб-сервера с помощью ключа API. –

ответ

14

Я думаю, вы не должны считать «ключи API» заменой токена доступа.

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

Поток я лично реализовать следующий:

  1. Пользователь подтверждает подлинность с типом гранта пароль с общим клиентом для каждого пользователя (т.е. ваш «веб-приложение» клиент, который является открытым, т.е. он не имеет client_secret).
  2. Пользователь может затем создать своего собственного клиента. Согласно спецификациям OAuth2, они не являются публичными, поэтому они состоят из client_id и client_secret. Это то, что вы называете «API-ключами».
  3. Пользователь может запросить токен доступа через своего клиента с любым типом гранта, который вы хотите поддерживать (например, прямые учетные данные клиента, код авторизации, неявные, третьи стороны и т. Д.). Вам нужно будет вкратце упомянуть о надлежащих методах обеспечения безопасности при работе с учетными данными клиента.

Очевидно, что вам нужно будет реализовать свой сервер OAuth2 таким образом, чтобы клиенты могли принадлежать определенным пользователям и имели разные приемлемые типы грантов (то есть вы не можете разрешать использование разрешения пароля с помощью пользовательского клиента, в то время как вы можете запретить любой тип гранта, отличный от пароля для вашего клиента веб-приложения).

После этого вы сможете определить токены TTL или их отсутствие на каждом клиенте или на основе типа гранта (например, токен доступа, запрошенный с помощью пароля, только для использования клиентом веб-приложения, будет иметь короткий TTL, тогда как разрешение на авторизационный код предоставит долгоживущие токены).
Я бы посоветовал полностью отказаться от TTL, и, скорее, использовать тип субсидии refresh_token для обновления истекших токенов доступа.

Кроме того, вам, вероятно, придется определить систему авторизации какого-либо определенного типа (ACL, RBAC, что угодно), чтобы определить, какой клиент может что-то сделать. Это означает, что каждый токен доступа должен содержать ссылку на клиент, используемый для его создания.

Таким образом, чтобы подвести итог, вот отношения:

ПользовательимеетClient.
КлиентимеетПользователь.
Клиентимеет многоТокен.
ТокенимеетКлиент.
TokenимеетПользователь.

YMMV on двусторонний.

Вы должны иметь возможность реализовать все, что я описал, с наиболее распространенными реализациями серверов OAuth2 любой платформы.

TL; "API ключи" на самом деле OAuth2 клиентов.

+0

Спасибо Stefano;). Звучит неплохо и вполне логично, хотя мне не очень нравится тот факт, что пользователю нужно передать как client_secret, так и client_id (что усложняет ситуацию). Я попытался понять, что API-интерфейс Stripe работал при анализе запросов, и, похоже, они использовали Basic auth с сгенерированным ключом API (который они должны были генерировать) и Bearer с токеном доступа (их webapp). –

+0

Ну, вы должны использовать учетные данные клиента только один раз, чтобы получить токен доступа, в то время как при обычной аутентификации вы отправляли фактические учетные данные с каждым запросом. Это сложнее, это правда, но это также безопаснее, если сделано правильно (как и все, что касается всего сравнения OAuth2 vs Basic). –

1

Я написал сообщение о том, как использовать токены доступа для приложений RESTful: https://templth.wordpress.com/2015/01/05/implementing-authentication-with-tokens-for-restful-applications/. Возможно, это может дать некоторые намеки.

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

Насколько я понимаю, у вас есть два вида пользователей ваших приложений:

  • конечных пользователей с помощью веб-интерфейса (логин с паролем через OAuth2)
  • Приложения (логин с ключами API)

Таким образом, я бы реализовал эти два вида пользователей и сделал их доступными для доступа к токенам. В обоих случаях для доступа к службам RESTful будут использоваться токены доступа.

Кроме того, я думаю, что этот ответ может дать вам несколько советов: Securing my REST API with OAuth while still allowing authentication via third party OAuth providers (using DotNetOpenAuth).

Надеюсь, что он отвечает на ваш вопрос. Thierry

2

Благодарим вас за ответ.

Я на самом деле довольно опыт работы с OAuth2, мой вопрос был более нацелен на ключи API. Мне нравится идея ключа API, использующего токен доступа, но я думаю, что это не сработает. Ключ API исправлен и не изменяется, а токен доступа может истечь.

Вопрос в том, как приложение может узнать, является ли это токеном доступа или ключами API. Я имею в виду, хорошо, допустим, что в моей базе данных каждый пользователь имеет столбец «api_key» в своей базе данных.

В отличие от токена доступа, api_key не истекает (хотя пользователь может в конечном итоге повернуть его). То, что я хочу, как я сказал, является однородной обработкой аутентификации.

Случай 1: мой собственный веб-приложение сделать API вызовы

Рабочий процесс выглядит следующим образом, используя oauth2:

  1. Пользователь вводит свой почтовый/пароль.
  2. Сервер авторизации возвращает токен доступа (например: «abc»).
  3. В веб-приложении все вызовы API выполняются с использованием этого токена. Например: «/ payments/1» с заголовком авторизации: «Bearer abc».

Ницца и простота.

Случай 2: пользователь имеет ключ API, который не истекает и может быть использовано в частном порядке в их собственном приложении

Очевидно, что механизм авторизации должен оставаться таким же. Итак:

  1. Пользователь заходит в свой аккаунт и читает, что его ключ API «def».
  2. В своем серверном коде они могут выполнять один и тот же вызов с тем же механизмом аутентификации. Поэтому он может называть «/ payments/1» авторизацией: «Определение несущей».

И он должен работать. Как вы можете видеть, в обоих примерах ничего не изменилось. Они получают доступ к одному и тому же ресурсу, одному и тому же механизму авторизации ... но в одном случае у нас есть токен доступа, а в другом случае у нас есть ключ API. И я понятия не имею, как я должен реализовывать это как с точки зрения базы данных, так и с помощью кода авторизации.

Одна потенциальная идея, которую я использовал, это использовать другой механизм auth. Для OAuth это будет «Authorization: Bearer accessToken», тогда как для API это будет обычная проверка подлинности: «Авторизация: базовый apiKey».

Звучит это хорошо?

Смежные вопросы