我怎么说服Django我登录了?

时间:2017-02-15 23:02:45

标签: python django python-3.x cookies

我有一个Django应用程序,我希望允许用户通过某些API登录,并允许他们使用受login_required装饰者保护的一些API调用:

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

这就是我尝试登录并从python shell调用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)

到目前为止一切顺利。我收到了sessionidcsrftoken个Cookie的回复。然后我尝试使用sessionid cookie来做事:

>>> 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 Cookie完美配合,因此我想我会遗漏一些标题,因为它们数量众多,只有HostUser-AgentSet-Cookie。< / p>

我故意试图避免使用Django和stdlib之外的模块。不应该认证很简单吗?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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)