我有一个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)
到目前为止一切顺利。我收到了sessionid
和csrftoken
个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完美配合,因此我想我会遗漏一些标题,因为它们数量众多,只有Host
,User-Agent
和Set-Cookie
。< / p>
我故意试图避免使用Django和stdlib之外的模块。不应该认证很简单吗?
答案 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)