Django使用python请求进行身份验证

时间:2018-11-01 12:32:45

标签: django post python-requests

在梳理如何根据django应用正确认证python-request客户端以允许POST时遇到麻烦。我们的代码尝试首先登录,然后使用已建立的python-request会话来处理POST数据,但是我们的POST请求始终未经身份验证。

这就是我们正在尝试的

# client.py
LOGIN_URL = 'http://localhost/accounts/login'
ADD_URL = 'http://localhost/add'

import requests
rqst = requests.session()
rsp = rqst.get(LOGIN_URL)

token = rsp.cookies['csrftoken']
rsp = rqst.post(LOGIN_URL, auth=(uname, pwd),
        data={'csrfmiddlewaretoken':token, 'next':'/'})
# at this point, rsp.status_code == 200 and we are logged in

payload = {'foo':'bar', 'csrfmiddlewaretoken':token}
rsp = rqst.post(ADD_URL, json=payload)
# Error -- this post always returns 403 -> HttpResponseForbidden

# view.py
def view_add(request):
    if request.user.is_authenticated:
        return HttpResponseForbidden('not authenticated')
    ...

我们已在settings.py中启用了django会话。使用相同的模式访问GET视图是没有问题的。这是我们遇到麻烦的唯一POST

有什么主意吗?

4 个答案:

答案 0 :(得分:1)

我想补充一下user590028的示例对我有帮助,但是出于某种原因,如果是这样设置服务器,则在LOGIN_URL之后添加/是很重要的。

在我项目的urls.py中:

    urlpatterns = [
    path('login/', auth_views.LoginView.as_view(template_name='users/login.html'), name='login'),
    ]

因此,此操作不起作用:http://localhost:8000/login <-不加斜杠!

这有效:http://localhost:8000/login/

...我花了很长时间才弄清楚这一点,因此希望对其他人有帮助。

也-有一篇非常不错的Python抓取文章,它也帮助我找到了csrf令牌: https://kazuar.github.io/scraping-tutorial/

答案 1 :(得分:0)

您的第二个POST请求没有CSRF令牌(即使登录请求也没有)。

除非您的视图被标记为@csrf_exempt,否则所有非GET请求都需要CSRF令牌。

答案 2 :(得分:0)

该问题是由我对Django身份验证的困惑引起的。 Django身份验证基于表单,而rqst.post(..., auth=(uname, pwd))默认为basic authentication

因此,错误是在rqst.post()的第一次调用中发生的。正确的代码client.py是:

# client.py
LOGIN_URL = 'http://localhost/accounts/login'
ADD_URL = 'http://localhost/add'

import requests
rqst = requests.session()
rsp = rqst.get(LOGIN_URL)

token = rsp.cookies['csrftoken']
rsp = rqst.post(LOGIN_URL, 
        data={'username':uname, 'password': pwd,  # <---- HERE IS FIX
        'csrfmiddlewaretoken':token, 'next':'/'})

答案 3 :(得分:-1)

在django项目之前,我在request.sessions上遇到过问题。我确信它是可行的,但是我发现将Selenium用作无头浏览器更加容易。 python对硒有很好的支持,并且入门非常简单。

https://selenium-python.readthedocs.io/