Django-CSRF:CSRF验证失败。单击登录按钮时请求中止

时间:2013-10-25 12:00:14

标签: django django-csrf

我正在尝试构建一个可以将数据添加到MySQL数据库的简单网站。我有一个带有两个文本输入的POST表单(用户名,密码)。我已经阅读了所有相关的答案,并试图解决它,但无法成功。

的index.html

<form action="/login/" method="post">{% csrf_token %}<table border="0" cellspacing="15" width="345" align="center">
<tr>
    <td width="100" >Username:</td>
    <td><input type="text" class="text-box" value="{{ username }}" placeholder="Username"/></td>                        
</tr>
<tr>
    <td class="align-left">Password:</td>
    <td><input type="password" class="text-box" value="" placeholder="Password"/></td>                        
</tr>                    
<tr>
    <td class="align-left"></td>
    forget-link"><a href="#" >Forget Your Passowrd?</a></td>                        
</tr>                    

     

views.py

def login(request):

    logout(request)
    username = password = ''
    if request.method :
        username = request.POST['username']
        password = request.POST['password']     
        user = authenticate(username=username, password=password)
        if user is not None:
            if user.is_active:
                login(request, user)
                return HttpResponseRedirect('/main/')
    return render(request, 'index.html',{ 'username': username})

urls.py

urlpatterns = patterns('',      

    url(r'^login/', 'mysite.views.login', name='login'),
)

我已经在index.html中的表单标记之后应用了{%csrf_token%}。

当我点击“登录”按钮时,出现以下错误:

CSRF verification failed. Request aborted.

2 个答案:

答案 0 :(得分:3)

问题是您在模板中使用了标签{%csrf_token%},但之前未在视图中生成令牌,因此模板对此一无所知。

docs之后,您有两个选择:

第一个解决方案:

  

使用始终使用的RequestContext   'django.core.context_processors.csrf'(无论你的是什么   TEMPLATE_CONTEXT_PROCESSORS设置)。如果您使用的是通用视图   或者contrib应用程序,您已经被覆盖,因为这些应用程序使用   整个RequestContext。

所以你必须改变视图中的代码:

def login(request):
    logout(request)
    username = password = ''
    if request.method :
        username = request.POST.get('username', '')
        password = request.POST.get('password', '')
        user = authenticate(username=username, password=password)
        if user is not None:
            if user.is_active:
                login(request, user)
                return HttpResponseRedirect('/main/')

    template = loader.get_template('index.html')
    context = RequestContext(request,{ 'username': username})
    return HttpResponse(template.render(context))

第二种解决方案:

  

手动导入并使用处理器生成CSRF令牌和   将其添加到模板上下文中。 e.g:

你的代码应该是(正如mcniac告诉你的那样):

def login(request):
    logout(request)
    username = password = ''
    if request.method :
        username = request.POST['username']
        password = request.POST['password']     
        user = authenticate(username=username, password=password)
        if user is not None:
            if user.is_active:
                login(request, user)
                return HttpResponseRedirect('/main/')
    context = { 'username': username}
    context.update(csrf(request))
    return render(request, 'index.html',)

答案 1 :(得分:1)

我认为你需要将csrf应用到你的上下文中,你的视图会像这样结束

from django.shortcuts import render_to_response
from django.core.context_processors import csrf

def login(request):

    logout(request) # not sure what this function is, I guess must be on some part of your code
    if request.method == "POST" :
        username = request.POST['username'] or ''
        password = request.POST['password'] or ''
        user = authenticate(username=username, password=password)
        if user is not None:
            if user.is_active:
                login(request, user)
                return HttpResponseRedirect('/main/')
    context = { 'username': username, }
    context.update(csrf(request))
    return render_to_response(request, 'index.html', context)