1

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

索引.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>                    

视图.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})

网址.py

urlpatterns = patterns('',      

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

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

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

CSRF verification failed. Request aborted.

4

2 回答 2

3

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

按照文档,您有两个选择:

第一个解决方案:

使用 RequestContext,它始终使用“django.core.context_processors.csrf”(无论您的 TEMPLATE_CONTEXT_PROCESSORS 设置如何)。如果您正在使用通用视图或贡献应用程序,那么您已经被覆盖,因为这些应用程序始终使用 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 令牌并将其添加到模板上下文中。例如:

你的代码应该是(正如 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',)
于 2013-10-25T12:45:01.763 回答
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)
于 2013-10-25T12:35:55.717 回答