2017-02-15 10 views
0

У меня есть приложение Django, и я хочу, чтобы пользователи могли войти через некоторые API и позволяют им использовать некоторые API вызовы, защищенные login_required декоратора:Как убедить Django Я вошел в систему?

@csrf_exempt 
def api_login(request): 
    if request.method == 'POST': 
     username = request.POST.get('username', '') 
     password = request.POST.get('password', '') 
     user = authenticate(username=username, password=password) 
     if user is not None: 
      login(request, user) 
      return HttpResponse(status=201) 
    return HttpResponseBadRequest() 

@login_required 
def do_stuff(request): 
    return HttpResponse(status=201) 

И это, как я пытаюсь войти и вызвать do_stuff из питона оболочки:

>>> from urllib.parse import urlencode 
>>> from urllib.request import Request, urlopen 
>>> post = Request('http://127.0.0.1:8000/api/login', urlencode({'username': 'admin', 'password': 'admin'}).encode()) 
>>> post_resp = urlopen(post) 

до сих пор так хорошо. Я получаю ответ с sessionid и csrftoken куки. Тогда я пытаюсь использовать sessionid печенье, чтобы делать такие вещи:

>>> get = Request('http://127.0.0.1:8000/api/do-stuff') 
>>> get.add_header('Set-Cookie', 'csrftoken=...') # just copy paste of the response cookie 
>>> get_resp = urlopen(get) 

На данный момент login_required декоратора думает, что я AnonimousUser и посылает переадресацию на страницу входа в систему. Браузер отлично работает с этим файлом sessionid, поэтому, я полагаю, я пропускаю некоторые заголовки, потому что их немного, только Host, User-Agent и Set-Cookie.

Я намеренно стараюсь избегать использования модулей вне Django и stdlib. Не должна ли быть достаточно простой аутентификация?

ответ

0

Оказалось, что Set-Cookie неправильный заголовок для последующих запросов. Cookie:

>>> get = Request('http://127.0.0.1:8000/api/do-stuff') 
>>> get.add_header('Cookie', 'csrftoken=53eX5pwRzV4fR...') # just csrftoken here 
>>> get_resp = urlopen(get) 
1

Попробуйте использовать тестовый клиент Django вместо urllib.

>>> from django.test import Client 
>>> c = Client() 
>>> response = c.post('/login/', {'username': 'john', 'password': 'smith'}) 
>>> response.status_code 
200 
>>> response = c.get('/customer/details/') 
>>> response.content 
b'<!DOCTYPE html...' 

См: documentation

+0

Хм, это выглядит очень перспективно! Как вы знаете, могу ли я отправить «Клиент» в виде отдельного пакета (без остальной части Django)? И подходит ли он для производства? – Vovanrock2002

+0

Извините ... Я никогда не пытался использовать его как отдельный пакет ... И, возможно, его следует использовать только в процессе тестирования. – awmleer