使用请求python库连接Django应用程序失败的身份验证

时间:2012-04-13 02:59:27

标签: python django authentication python-requests

这里可能是一个愚蠢的问题: 请求(一个python HTTP lib)是否支持Django 1.4?

我使用请求按照以下官方快速入门进行操作:

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

但我从未获得正确的身份验证。(当然我一次又一次地检查了网址,用户名和密码。)

以上网址“ http://127.0.0.1:8000/getAllTracks ”匹配Django项目的url.py的网址格式,该网址格式的回调是' getAllTracks '查看Django应用程序。

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

视图的验证码实际上非常简单,完全如下(第二行):

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

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

任何帮助都将不胜感激。

3 个答案:

答案 0 :(得分:11)

在Django中,身份验证的工作方式如下:

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

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

您必须首先调用您进行身份验证的视图并登录该用户。此视图的响应将在Cookie中包含sessionid

您应该使用此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

答案 1 :(得分:3)

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

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