编写 django-piston 客户端的正确方法是什么?

发布于 2024-10-08 01:21:18 字数 513 浏览 0 评论 0原文

我已经阅读了很多关于 django-piston 的文章,并使用它为我正在开发的应用程序制作 API,但我对世界的客户端很着迷。我已经编写了处理程序和 uri 映射,并且可以随心所欲地返回 JSON 或 XML。我陷入困境的是现在该怎么办。

我理想的结局是让 iPhone 和 Android 客户端消费并返回数据,但我不知道处理身份验证的正确方法。我能想到的最简单的方法是将用户名和密码保存在设备上,并用它标记每个请求,最终使用基本身份验证,但这会造成错误。我研究了piston对OAuth的支持,并在本教程,但这也不是正确的答案。最终,我真的很想在设备上有一个简单的用户名和密码提示,这些将通过 Piston 和 REST 发送到 Django,并且 API 密钥将返回。设备将存储该密钥并用它标记所有后续请求。这感觉是正确的方法,但我不知道该怎么做。有人能指出我正确的方向吗?

I've been reading a lot on django-piston and using to to make an API for an app I'm development, but I'm getting hung up on the client side of the world. I've written the handlers and uri mappings, and I can return JSON or XML to my heart's content. Where I'm getting stuck is what to do with that now.

My ideal endgame is to have an iPhone and Android client consume and return data, but I don't know the right way to handle authentication. The easiest way I can figure is saving the username and password on the device and tagging each request with it, ultimately using Basic Authentication, but that wreaks of wrong. I've looked in to piston's support for OAuth and gotten it working with the help of this tutorial, but that doesn't feel like the right answer, either. Ultimately, I'd really like to have a simple prompt on the device for username and password, those will be sent up to Django via Piston and REST, and an API key will return down. The device will store that key and tag all subsequent requests with it. That feels like the right way, but I can't figure out how to do it. Can any one point me in the right direction?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

何止钟意 2024-10-15 01:21:18

您可以编写自己的身份验证模块。下面是一个示例:

class ApiKeyAuthentication(object):

    def is_authenticated(self, request):
        auth_string = request.META.get("HTTP_AUTHORIZATION")

        if not auth_string:
            return False

        key = get_object_or_None(ApiKey, key=auth_string)

        if not key:
            request.user = AnonymousUser()
            return False

        request.user = key.user

        return True

    def challenge(self):
        resp = HttpResponse("Authorization Required")
        resp['WWW-Authenticate'] = "Key Based Authentication"
        resp.status_code = 401
        return resp

您需要一个模型来存储 API 密钥到用户的映射:

class ApiKey(models.Model):
    user = models.ForeignKey(User, related_name='keys')
    key = models.CharField(max_length=KEY_SIZE)

您需要某种方法来生成实际密钥。像这样的东西会起作用(例如,在 ApiKey 模型的 save 方法中:

key = User.objects.make_random_password(length=KEY_SIZE)

while ApiKey.objects.filter(key__exact=key).count():
    key = User.objects.make_random_password(length=KEY_SIZE)

最后,连接新的身份验证后端:

# urls.py

key_auth = ApiKeyAuthentication()

def ProtectedResource(handler):
    return resource.Resource(handler=handler, authentication=key_auth)

your_handler = ProtectedResource(YourHandler)

至于将用户名/密码交换为 API 密钥,只需编写一个使用 BasicAuthentication 的处理程序即可创建并返回新的 ApiKey(用于 request.user)。

You can write your own authentication module. Here's an example:

class ApiKeyAuthentication(object):

    def is_authenticated(self, request):
        auth_string = request.META.get("HTTP_AUTHORIZATION")

        if not auth_string:
            return False

        key = get_object_or_None(ApiKey, key=auth_string)

        if not key:
            request.user = AnonymousUser()
            return False

        request.user = key.user

        return True

    def challenge(self):
        resp = HttpResponse("Authorization Required")
        resp['WWW-Authenticate'] = "Key Based Authentication"
        resp.status_code = 401
        return resp

You'll need a model to store a mapping of API keys to Users:

class ApiKey(models.Model):
    user = models.ForeignKey(User, related_name='keys')
    key = models.CharField(max_length=KEY_SIZE)

You'll need some method to generate the actual keys. Something like this will work (say, in the ApiKey model's save method:

key = User.objects.make_random_password(length=KEY_SIZE)

while ApiKey.objects.filter(key__exact=key).count():
    key = User.objects.make_random_password(length=KEY_SIZE)

Lastly, hook up your new authentication backend:

# urls.py

key_auth = ApiKeyAuthentication()

def ProtectedResource(handler):
    return resource.Resource(handler=handler, authentication=key_auth)

your_handler = ProtectedResource(YourHandler)

As for swapping username / password for an API key, just write a handler that uses BasicAuthentication to create and return new ApiKey (for request.user).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文