【发布时间】:2015-11-15 03:54:42
【问题描述】:
我的网站使用 Django 的默认身份验证模块进行用户身份验证。通常情况下,用户只需要在登录页面填写一个html表单,用他/她的用户名和密码点击提交,那么受CSRF保护的数据就会被发布到Django auth端点/auth/login/。
但现在由于某种原因,我还需要在我的服务器上执行此操作。这是与后端身份验证服务器相同的服务器。经过研究和反复试验,我终于得到了:
from django.views.generic import View
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_protect
import requests
class fb_login(View):
"login view for Facebook OAuth"
@method_decorator(csrf_protect)
def get(self, request):
''' code that gets username and password info. from user's FB profile
is not shown here '''
# login code
url = 'http://localhost:8000/auth/login/'
client = requests.session()
# Retrieve the CSRF token first
client.get(url) # sets cookie
csrftoken = client.cookies['csrftoken']
form = {'username': uname, 'password': pw}
header = {'X-CSRFToken': csrftoken}
resp = requests.post(url, data=form, headers=header)
我还尝试将 csrf 令牌添加为表单字段的一部分:
form = {'username': uname, 'password': pw , 'csrfmiddlewaretoken': csrftoken}
resp = requests.post(url, data=form)
我几乎只是关注Django doc。但我仍然收到 403 错误说CSRF verification failed, CSRF cookie not set。我想知道我是否在这里遗漏了什么?我已经根据 Django 文档仔细检查了该过程,但我找不到任何可能错误或缺失的内容。
【问题讨论】:
-
您的页面模板是否在表单标签内包含
{% csrf_token %}? -
@JohnGordon 是的。在客户端登录没有问题,这是使用 {% csrf_token %} 的典型表单发布操作。但现在我需要在服务器端实现这一点。
-
我刚刚查看了从我的一个表单发送的数据,它发送表单数据
csrfmiddlewaretoken=xxx和cookiecsrftoken=xxx。也许您需要设置 cookie 而不是/除了表单字段。 -
@rodrigo 感谢您的帮助!你知道如何在服务器代码中设置cookie吗?谢谢。
-
@JFreebird:嗯,我使用 CSRFMiddleware 和
render()函数作为我的视图,我自动拥有它。请参阅the docs 了解替代方案。