3

也许这里有一个愚蠢的问题: Requests(A python HTTP lib) support Django 1.4 吗?

我使用请求遵循官方快速入门,如下所示:

requests.get('http://127.0.0.1:8000/getAllTracks', auth=('myUser', 'myPass'))

但我从来没有得到正确的身份验证。(当然我已经一次又一次地检查了网址、用户名、密码。)

上面的 url ' http://127.0.0.1:8000/getAllTracks ' 匹配 Django 项目的 url.py 的 url 模式,并且该 url 模式的回调是 Django 应用程序的 ' getAllTracks ' 视图。

如果我注释掉“ getAllTracks ”视图的身份验证代码,那么上面的代码可以正常工作,但是如果我为视图添加这些身份验证代码,那么上面的代码永远不会得到正确的身份验证。

视图的认证代码其实很简单,如下图(第二行):

def getAllTracks(request):
    if request.user.is_authenticated():
        tracks = Tracks.objects.all()
        if tracks:
            # Do sth. here

这意味着如果我删除上面的第二行(当然还有一些缩进调整),那么requests.get()操作会为我做正确的事情,但如果不是(保留第二行),那么它永远不会正确。

任何帮助,将不胜感激。

4

3 回答 3

14

在 Django 中,身份验证以下列方式工作:

  • 有一个 SessionMiddleware 和 AuthenticationMiddleware。在调用任何视图之前调用这两个类的 process_request()。
  • SessionMiddleware 在较低级别使用 cookie。它检查一个名为的 cookiesessionid并尝试将此 cookie 与用户相关联。
  • AuthenticationMiddleware 检查此 cookie 是否与用户相关联,然后设置request.user为相应的用户。如果 cookiesessionid未找到或无法与任何用户关联,则request.user设置为AnonymousUser().
  • 由于 Http 是无状态协议,django 使用这两个中间件并在较低级别使用 cookie 为特定用户维护会话。

来到代码,以便requests可以与 django 一起使用。

您必须首先调用您验证和登录用户的视图。此视图的响应将包含sessionid在 cookie 中。

你应该使用这个 cookie 并在下一个请求中发送它,以便 django 可以验证这个特定的用户并让你request.user.is_authenticated()通过。

from django.contrib.auth import authenticate, login

def login_user(request):
    user = authenticate(username=request.POST.get('username'),  password=request.POST.get('password'))
    if user:
       login(request, user)
       return HttpResponse("Logged In")
    return HttpResponse("Not Logged In")

def getAllTracks(request):
    if request.user.is_authenticated():
        return HttpResponse("Authenticated user")
    return HttpResponse("Non Authenticated user")

提出请求:

import requests

resp = requests.post('http://127.0.0.1:8000/login/', {'username': 'akshar', 'password': 'abc'})

print resp.status_code
200 #output

print resp.content
'Logged In' #output

cookies = dict(sessionid=resp.cookies.get('sessionid'))

print cookies
{'sessionid': '1fe38ea7b22b4d4f8d1b391e1ea816c0'}  #output

response_two = requests.get('http://127.0.0.1:8000/getAllTracks/', cookies=cookies)

cookies请注意,我们使用关键字参数传递 cookie

print response_two.status_code
200  #output 

print response_two.content
'Authenticated user'  #output

所以,我们的request.user.is_authenticated()工作正常。

response_three = requests.get('http://127.0.0.1:8000/hogwarts/getAllTracks/')

请注意,我们不会在此处传递 cookie。

print response_three.content
'Non Authenticated user' #output
于 2013-04-15T18:29:21.857 回答
3

我猜,authRequests 的关键字启用了HTTP Basic 身份验证,这不是 Django 中使用的。您应该使用 POST 数据中提供的用户名和密码向项目的登录 url 发出 POST 请求,之后您的 Requests 实例将收到一个包含已保存身份验证数据的会话 cookie,并且能够成功请求受身份验证保护的视图。

于 2012-04-13T03:27:53.327 回答
1

您可能更容易在初始身份验证时设置一个 cookie,将其传递回客户端,然后对于未来的请求,期望客户端在标头中发回该令牌,如下所示:

r = requests.post('http://127.0.0.1:8000', auth=(UN, PW))
self.token = r.cookies['token']
self.headers = {'token': token}

然后在进一步的电话中,假设你在同一个班级,你可以这样做:

r = requests.post('http://127.0.0.1:8000/getAllTracks', headers=self.headers)
于 2013-04-15T15:44:55.587 回答