ajax页面加载后没有csrf令牌 [英] no csrf token after ajax page load

查看:146
本文介绍了ajax页面加载后没有csrf令牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在我设置了这样一来,当登陆成功登录时,登录名会变淡,出现一个注销按钮。我想要能够登录注销,并转到我的注销功能,只是重定向到原始的登录页面,但由于某些原因(只有成功)ajax表单提交突然之后,我遇到403错误:为故障原因:CSRF令牌丢失或不正确。

Right now I have it set up so that when a successful login occurs the login div fades and a logout button appears. I want to be able to hit the logout and go to my logout function that just redirects to the original login page, but for some reason after the (only successful) ajax form submission suddenly I am getting 403 errors : Reason given for failure: CSRF token missing or incorrect.

想知道问题是否我没有正确传递CSRF令牌。我已尝试过页面上的所有内容。 https://docs.djangoproject。 com / en / 1.6 / ref / contrib / csrf /#ajax

Wondering if the problem is that I'm not passing the CSRF token correctly. I've tried everything on the page https://docs.djangoproject.com/en/1.6/ref/contrib/csrf/#ajax

这是我的代码:

urls.py

from django.conf.urls import patterns, include, url

from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    # Examples:
    # url(r'^$', 'reportgenerator.views.home', name='home'),
    # url(r'^blog/', include('blog.urls')),

    url(r'^admin/', include(admin.site.urls)),
    url(r'^login/', 'reportgenerator.views.login'),
    url(r'^logout/', 'reportgenerator.views.logout'),
)

views.py


views.py

class LoginForm(forms.Form):
username = forms.CharField(max_length=200)
password = forms.CharField(max_length=200)

def login(request):
    c = {}
    c.update(csrf(request))

    if request.POST:
        form = LoginForm(request.POST)
        if form.is_valid():
            user = auth.authenticate(username = form.cleaned_data['username'],
                password = form.cleaned_data['password'])
            is_success = False
            if user is not None:
                auth.login(request, user)
                is_success = True

            if request.is_ajax():
                if (is_success):
                    return render_to_response('login.html', c, context_instance = RequestContext(request))

            return render('was_failure')
    else:
        form = LoginForm()

    c['form'] = form
        return render(request, 'login.html', c)

def logout(request):
        auth.logout(request)
        return HttpResponseRedirect('/login/')

和我的javascript:

and my javascript:

function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie != '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) == (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}

var csrftoken = getCookie('csrftoken');

function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

function sameOrigin(url) {
    // test that a given url is a same-origin URL
    // url could be relative or scheme relative or absolute
    var host = document.location.host; // host + port
    var protocol = document.location.protocol;
    var sr_origin = '//' + host;
    var origin = protocol + sr_origin;
    // Allow absolute or scheme relative URLs to same origin
    return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
        (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
        // or any other URL that isn't scheme relative or absolute i.e relative.
        !(/^(\/\/|http:|https:).*/.test(url));
}

$.ajaxSetup({
    beforeSend: function(xhr, settings) {
        if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) {
            // Send the token to same-origin, relative URLs only.
            // Send the token only if the method warrants CSRF protection
            // Using the CSRFToken value acquired earlier
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
    }
});

jQuery(function() {
  var form1 = jQuery("#contactform");

  form1.submit(function(e) {
    $.ajax({
        type: "POST",
        url: form1.attr('action'),
        data: form1.serializeArray(),
        success: function() {
            popup.setAttribute("style","display: none;");
            blurback.setAttribute("style", "-webkit-filter: blur(0px)");
            $("#welcome").fadeIn("slow");
            $("#logoutfade").fadeIn("slow");
        },
        error: function() {
            document.getElementById("password").value = "";
        }
    });
      e.preventDefault(); 
  });
});


推荐答案

跟进这个 - 我想出了一个几天后。我遇到这个问题的原因是因为注销按钮在ajax登录之前。当用户进行身份验证时,crsf令牌被重新生成,并且注销按钮的页面具有附加到它的旧标记,因为它是先前生成的。在ajax调用之后,我切换到生成登录按钮,一切都很好。

To follow up on this -- I figured out a couple days later. The reason I was having this problem was because the logout button was present before the ajax login. When the user was authenticated the crsf token was re-generated and the logout button the page had the old token attached to it because it was generated previously. I switched it to generating the login button after the ajax call and everything worked great.

这篇关于ajax页面加载后没有csrf令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆