python - 使用 API key 对开发人员进行身份验证,并使用基本身份验证/OAuth 对用户进行身份验证

标签 python django api rest tastypie

我四处寻找这个问题,但似乎找不到规范的答案。我正在尝试遵循最佳实践。也许我的想法是错误的。

我将 API 用户视为两种不同的类型:开发人员和最终用户,在不同的应用程序中使用不同的 django 模型。

开发人员将为 API 构建客户端,并且无需用户登录即可访问 API 的某些资源。为了限制他们的访问权限,我会要求他们注册并作为交换给他们一个 API key 。我们还想测试一下,使用 Angular 和 iOS 应用程序构建一个网站前端。 一旦这些开发人员构建了他们的 API 客户端,我网站上已经创建用户帐户的用户将使用开发人员创建的 API 客户端。在这些客户端的请求中,我期望有一个开发人员名称、api_key 以及用户名/密码(摘要,如果它是我们自己的可信客户端和第三方开发人员的 oauth token )。这需要检查 1) 是否允许开发人员通过检查其 APIKey 来使用 API,以及 2) 对最终用户进行身份验证。这在 Tastypie 中可能吗?

我的处理方式是错误的吗?我该如何进行双重身份验证?

最佳答案

我们使用这个确切的方案运行一个生产站点。当然,您必须自己进行调整。但总体想法是好的。您也可以安装一些 OAuth,但我们发现这不值得。对于大多数情况而言,OAuth 过于复杂。

我将大致解释一下我们的工作。

这是应用程序/开发人员部分:

  1. 我们识别“应用程序”(iOS、Android、BB、网站)。每个应用程序都有一个 ApiClient 实例模型。 ApiClient 具有三个属性:名称、公钥和私钥。

  2. 我们通过安全 channel 与 ApiClient 所有者(应用程序)交换公钥和私钥。

  3. 应用程序必须发送每个请求,指示公钥和使用私钥生成的签名(使用 hmac)。

  4. 每次我们收到请求时,我们都会从请求中获取公钥,在数据库中查找它,看看它属于哪个应用程序(名称)并检查签名。如果一切正常,则请求已满足。

对于用户身份验证部分:

  1. 为了验证用户身份,我们使用其他模型 ApiKey(由 tastypie 提供)。每个用户都有一个 ApiKey。该模型存储一个唯一的(我们可以说是随机的)字符串。当用户访问应用程序时,他/她会登录您的 API。该应用程序应发出类似于此的请求:

    POST/api/v1/login/ { '用户名': 'XXX', ‘密码’:‘XXX’ }

    (请注意,始终需要通过之前的公钥/私钥验证)

  2. 如果用户提供了正确的凭据,我们将返回 ApiKey 唯一 key 。

  3. 应用程序按照该用户的行为发出的每个后续请求都必须包含 key 。这就是您识别哪个用户正在尝试执行每个操作的方式。

最后一部分的示例:

  1. 用户 Jon 登录 iOS 应用。 (使用常规用户名和密码)
  2. 应用发送请求:

    POST/api/v1/login/ { '用户名': '乔恩', ‘密码’:‘雪’ }

  3. 我们有一个login API 方法。我们检查用户是否存在以及通行证是否正常。假设没问题。

  4. 我们发送了 ApiKey 信息:

    200 好 { '用户名': '乔恩', “ key ”:“$123$” }

  5. 应用程序已对用户进行身份验证。它需要使用这些凭据。

  6. 用户尝试在您的应用中执行某些操作。假设他尝试从您的应用程序获取日期时间。该应用程序将发出此请求:

    获取/api/v1/日期/

    授权:A​​piKey jon:$123$

就是这样。这不是 super 安全。 ApiKey 不会失效。但那是因为我们创建了自己的内部应用程序。值得注意的是,我们从中借用了 Tastypie 的一些东西。看看这个:http://django-tastypie.readthedocs.org/en/latest/authentication.html#apikeyauthentication

关于python - 使用 API key 对开发人员进行身份验证,并使用基本身份验证/OAuth 对用户进行身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16533293/

相关文章:

python - 需要条件和转换的计算字段的 Django 查询表达式

python - 如何加快url生成速度?

python - 不能模拟被模拟对象的方法? pytest 中的 call_count 为 0

python - 字符串到 int 的转换错误?

python - 无法部署到 heroku - 没有命名的模块

mysql - 自动从 Mysql 表中删除记录

python - Python 中基于 Widget 的 Web 框架(类似于 vaadin、GWT 或 zkoss)

r - 使用R构建RESTful API

c - 绘画后 WM_PAINT 不显示

javascript - 深入了解 json 数据