我环顾四周,但似乎无法找到一个规范的答案。我正在努力遵循最佳做法。也许我正在以错误的方式思考它。
我认为我的API用户有两种不同的类型:开发人员和最终用户,在不同的应用程序中使用单独的django模型。
开发人员将为API构建客户端,并且无需用户登录即可访问API的某些资源。为了限制他们的访问,我要求他们注册并交换给他们一个API密钥。我们还应该说,使用Angular和iOS应用程序构建网站前端。 一旦这些开发人员构建了他们的API客户端,我的网站用户(已经创建了一个用户帐户)将使用开发人员创建的API客户端。在这些客户的请求中,我希望有一个开发人员名称,api_key以及用户名/密码(摘要,如果是我们自己的可信客户端和oaduth令牌,那么对于那些开发者来说)。这将需要检查1)允许开发人员通过检查他们的APIKey来使用API,以及2)验证最终用户。这有可能在tastypie?
我是以错误的方式来做这件事的吗?我该如何进行双重身份验证?
答案 0 :(得分:1)
我们使用这个确切的方案运行生产站点。当然,你必须自己进行调整。但总体思路很好。你也可以有一些OAuth,但我们发现它不值得。对于大多数情况来说,OAuth太复杂了。
我将大致解释我们的工作。
这是应用程序/开发人员部分:
我们识别“应用”(iOS,Android,BB,网站)。每个应用都有一个ApiClient实例模型。 ApiClient有三个attrs:名称,公钥和私钥。
我们通过安全渠道与ApiClient所有者(应用程序)交换公钥和私钥。
应用程序必须发送每个指示公钥的请求和使用私钥生成的签名(使用hmac)。
每当我们收到请求时,我们都会从请求中获取公钥,在数据库中查找,查看它所属的应用程序(名称)并检查签名。如果一切正常,请求就会完成。
对于用户身份验证部分:
要对用户进行身份验证,我们使用其他型号ApiKey(由tastypie提供)。每个用户都有一个ApiKey。该模型存储一个唯一的(我们可以说是随机的)字符串。当用户访问应用程序时,他/她将登录到您的API。该应用程序应发出类似于此的请求:
POST / api / v1 / login / { 'username':'XXX', '密码':'XXX' }
(请注意,它始终需要传递以前的公钥/私钥auth)
如果用户提供了正确的凭据,我们会返回ApiKey唯一密钥。
应用程序在该用户的行为中发出的每个后续请求都必须包含该密钥。这就是您确定哪个用户尝试执行每项操作的方式。
最后一部分的一个例子:
该应用发送请求:
POST / api / v1 / login / { 'username':'jon', '密码':'雪' }
我们有一个login
API方法。我们检查用户是否存在以及传递是否正常。假设没关系。
我们发送了ApiKey信息:
200 OK { 'username':'jon', 'key':'$ 123 $' }
该应用已对用户进行了身份验证。它需要使用这些凭据。
用户尝试在您的应用中执行某些操作。假设他试图从你的应用程序中获取日期时间。该应用程序将发出此请求:
GET / api / v1 / date /
授权:ApiKey jon:$ 123 $
就是这样。这不是超级安全的。 ApiKeys不会失效。但那是因为我们创建了自己的内部应用程序。值得注意的是,我们从Tastypie那里借了一些东西。看看这个:http://django-tastypie.readthedocs.org/en/latest/authentication.html#apikeyauthentication
答案 1 :(得分:0)
这是切线的,但您可能要签出drf-keypair-permissions。
这是一个Django模块,它使用非对称的公共/专用密钥对来使用预共享密钥对HTTP请求进行签名和验证。它可以将每个公钥与用户配对,因此授权可以作为登录名加倍,并且可以扩展以管理API限制。
它支持几种算法,包括RSA-SHA和椭圆曲线,并且可以在管理区域中管理密钥。
它使用IETC Cavage-12 draft standard来处理授权签名