django-tastypie:为什么api密钥有用以及如何支持多个auth方案?

时间:2013-07-07 03:09:20

标签: django api tastypie django-authentication

我正在设计一个网站,其中人们将以用户身份登录,并且可能分为多个群组,这些群组有几种不同的类型。我想要一个人们可以直接使用的网站,以及公开可以被其他网站使用的API。

实施登录系统的最佳方式是什么,该登录系统既适用于网站本身的常规用户,也允许API消费网站代表用户无缝创建帐户并允许用户查看其数据来自我的网站和API消费网站?

我正在使用Django 1.5,所以我愿意自定义用户模型等等。 API将使用Tastypie提供。

编辑:老实说,我的主要问题是,我不太了解API密钥何时有用,以及它们如何与常规用户登录共存(如果有)。

3 个答案:

答案 0 :(得分:11)

用例:

API密钥的第一个和用例是自动化。您将api key(或通常称为token)提供给第三方,瞧,您可以让第三方为您执行操作。当您不再信任第三方时,您可以撤销api key或重新生成它。 Api键允许用户启动&通过传统的身份验证(例如username/password)请求令牌来验证操作链,然后用户将其传递给感兴趣的各方。最后看看我关于电话号码的小故事。

为什么不使用密码?

因为您不想让其他网站上的用户受到损害,并让他们在那里输入密码才能使用您的API。如果第三方遭到入侵,则用户的通信或密码将受到损害。

以下是很好的资源:


带有tastypie的Api键

这是good starting point

from django.contrib.auth.models import User
from django.db import models
from tastypie.models import create_api_key
models.signals.post_save.connect(create_api_key, sender=User)

由于post_save信号,这应该照顾创建api密钥。第二部分是允许多个身份验证方案适合您的用例,所以...到MultiAuthentication

from django.contrib.auth.models import User
from tastypie.authentication import BasicAuthentication, ApiKeyAuthentication, MultiAuthentication
from tastypie.authorization import DjangoAuthorization
from tastypie.resources import ModelResource

class UserResource(ModelResource):
    class Meta:
        queryset = User.objects.all()
        resource_name = 'auth/user'
        excludes = ['email', 'password', 'is_superuser']

        authentication = MultiAuthentication(BasicAuthentication(), ApiKeyAuthentication())
        authorization = DjangoAuthorization()

其他考虑因素

这些是绝对不会泄露网络上敏感数据的好习惯:

  • 如果没有ssltls
  • ,请勿进行任何用户/密码身份验证
  • 不使用ssltls
  • 的http基本身份验证
  • 锁定用户不应使用permissions访问的资源。
  • 确保您的回复具有正确的cache-control标题
  • 始终允许用户重置/重新生成/删除其令牌/ api密钥。
  • 用户不需要只有一个api密钥,你可以拥有其中几个;每个第三方一个。

我使用gmail所以这里是https://security.google.com/settings/security(审核权限)的示例,我可以看到如何使用google openid:

revoking permissions for google openid

为什么要为每个第三方使用一个api密钥?为什么你应该允许用户拥有多个api密钥并为特定用途标记它们?

答案是如果api key与您的phone number分享的内容相同,但您不需要向所有朋友提供相同的电话号码(谷歌语音FTW!)。

  • 案例1:一个电话号码。

如果你的朋友行为不端并把它交给了一大堆销售代表,你会非常生气。如果您的手机是相同的,那么拥有它的人可能会在不知情的情况下与其他人分享。最终结果,所有销售代表都知道你的号码...不太好。但你仍然希望你妈妈能打电话给你,对吗?所以你不能真正改变你的号码。现在想象一个更危险的情况;你在当地比萨店有一个标签,他们通过姓名/电话号码了解你。如果有人拿到你的api密钥,他们可能冒充你订购披萨并仍然向你收费(你有一个标签!)。

  • 案例2:多个电话号码:

如果您有100个号码给100个不同的朋友,他们不仅可以与您联系,而且如果销售代表给您打电话,您会知道您的哪位朋友放弃了,您可以直接切那个号码。妈妈现在开心了,因为她可以告诉你去哪儿吃早午餐。你的朋友现在决定订购比萨饼......现在你可以将它追踪给你的朋友(或者你应该给比萨饼店提供一个你朋友都不知道的数字。)

答案 1 :(得分:0)

从安全角度来看,有两个主要的“API密钥”类别,每个类别具有不同的用途:

  • 一个随机的API密钥,有点像密码和用户名组合:它被硬连线到客户端配置文件中,被认为是一个秘密。只需拥有此密钥,即可访问API。因为密钥表示标识客户端的秘密(因此验证信任),所以必须随每个请求一起发送秘密。必须信任该连接以确保不会截获该密钥,这意味着所有API访问都必须要求TLS / SSL。通常只使用第一个请求上的密钥来扩展此方法,其中使用链接到客户端IP地址的旋转会话密钥执行连接的其余部分(就像登录网站一样)
  • 非对称签名方案:像DSA或RSA这样的非对称密码用于创建存储在客户端配置中的密钥。秘密永远不会在网络上共享,而是加密每个API请求的散列。服务器保持链接到每个私钥的公钥,该私钥解密每个请求的散列签名,然后创建自己的要验证的散列。这是执行API身份验证的推荐和理想方式,因为它不需要TLS / SSL,也不需要会话管理策略。

我不知道django的API身份验证库,并建议查看Amazon AWS基于HMAC非对称签名的方法的源代码,以实现出色的实现。

答案 2 :(得分:0)

我会设计系统,以便每个请求都需要一个API密钥。理想情况下,您将其放在每个请求的Authorization标头中。 API应该尽可能纯粹是RESTFul,即没有会话处理。我认为这对于良好的API设计非常重要。

完成该部分后,您的用户将在完全相同的庄园中访问该网站。但是,他们不会记住他们的API密钥,而只记住他们的凭据。因此,有一个登录页面根据其凭据对用户进行身份验证,然后返回api密钥以存储在客户端的会话中。从那时起,所有请求都应使用API​​密钥授权。