Как правильно написать Django-поршневой клиент? - PullRequest
8 голосов
/ 16 декабря 2010

Я много читал о django-поршне и использовал для создания API для приложения, которое я разрабатываю, но я зациклен на клиентской стороне мира. Я написал обработчики и сопоставления URI, и я могу вернуть JSON или XML к своему сердцу. То, что я застрял, это то, что с этим делать сейчас.

Мой идеальный финал - иметь клиент iPhone и Android, использующий и возвращающий данные, но я не знаю, как правильно обращаться с аутентификацией. Самым простым способом, который я могу себе представить, является сохранение имени пользователя и пароля на устройстве и пометка каждого запроса им, в конечном счете, с использованием обычной аутентификации, но это неправильно. Я посмотрел на поддержку поршня для OAuth и заставил его работать с помощью этого урока , но это также не похоже на правильный ответ. В конечном счете, мне бы очень хотелось, чтобы на устройстве была простая подсказка для имени пользователя и пароля, они будут отправлены в Django через Piston и REST, а ключ API вернется вниз. Устройство сохранит этот ключ и отметит все последующие запросы им. Это похоже на правильный путь, но я не могу понять, как это сделать. Может кто-то указать мне верное направление?

1 Ответ

22 голосов
/ 17 декабря 2010

Вы можете написать свой собственный модуль аутентификации. Вот пример:

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)

Вам понадобится какой-то метод для генерации реальных ключей. Примерно так будет работать (скажем, в методе save модели ApiKey:

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).

...