【问题标题】:Django csrf_token is null in chromeDjango csrf_token 在 chrome 中为空
【发布时间】:2014-09-25 22:25:27
【问题描述】:

我遇到了一个奇怪的问题。我正在编写一个简单的小应用程序,需要将一些内容发布回 django 视图。我在这里遵循指南:https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/ 设置 ajax 标头并在我的 js 中有以下代码:

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');
console.log(csrftoken)

function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
    beforeSend: function(xhr, settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
    }
});

我的 html 中有一个带有代码的表单:

<form onsubmit="return false;">
                {% csrf_token %}
                <input type="text" id="map-id-input"/>
                <button id="map-id-btn" class='btn btn-default custom-btn'>
                    Go 
                </button>
            </form>

我还有一个 js 代码的 sn-p,当点击上面的按钮时运行:

$(function() {
$("#map-id-btn").click(function() {
    checkMapID();
})
})

function checkMapID() {
    var mapId = $("#map-id-input").val();
    $.ajax({
        url: "check_map_id/", 
        type: "POST",
        dataType: "json", 
        data: {
            csrfmiddlewaretoken: csrftoken,
            map_id: mapId,
        },
        success: function(status_dict) {
            if (status_dict.status === 1) {
                $("#status").html("Valid map ID <br> Loading Data...")
                window.location = status_dict.url;
            }
            else {
                $("#status").html("Invalid map ID. Please try again, or contact ...")
            }
        },
        error: function(result) {
            console.log(result)
        }
    });
}

我所有的 Javacript 都在一个文件中,位于模板的顶部。

捕获 url 'check_map_id/' 的视图是:

@ensure_csrf_cookie
def check_map_id(request):
map_id = request.POST['map_id']

if map_id not in GEOJSON_LOOKUP.keys():
    status = json.dumps({
        'status': 0,
        'url': '',
    })  
    return HttpResponse(status, content_type="application/json")
else:
    status = json.dumps({
        'status': 1,
        'url': reverse('map', args=(map_id,)),
    })
    return HttpResponse(status, content_type="application/json")

现在,当我使用 firefox 在本地计算机上运行应用程序时,我得到一个有效的 csrf 令牌被打印到控制台。如果我在本地机器上用 chrome 或 IE 启动应用程序,我会打印一个空值。相同的行为在实时站点上得到回应。我正在使用 linux (mint),奇怪的是,如果我在 windows 机器上的 firefox 中启动应用程序,它也会在 firefox 中返回 null。这里发生了一些奇怪的事情!有任何想法吗?我似乎完全按照 django 文档的建议进行操作。

更新: 我将@ensure_csrf_cookie 添加到我的索引视图中,现在我在本地机器上的两个浏览器上都打印出一个令牌。但是,该代码无法在我的实时服务器上运行。如果我在我的 js 中添加一些随机的 console.logs,它会显示在实时服务器上,因此代码正在运行。我真的很茫然。

更新2: 所以我已经确定问题是在我的实时站点上,没有设置 document.cookie 属性。我猜 csrftoken="..." cookie 是由 django 设置的。它似乎是在我的本地机器上设置它,而不是在我的实时站点上。代码是相同的:/。这到底是怎么回事?!

【问题讨论】:

    标签: ajax post django-views csrf django-csrf


    【解决方案1】:

    好的。我发现了问题!这是一个简单的案例,首先实际上并未将 csrf 令牌发送到 html 页面。我专注于 ajax 调用,这实际上是正确的。

    我将实际呈现违规表单所在页面的视图更改为:

    @ensure_csrf_cookie
    def index(request):
        context = RequestContext(request)
        return render_to_response('vis_it_app/index.html', context)
    

    这里的关键是 'RequestContext',默认情况下,它也会发送 csfr 令牌。那是一个任务……

    总结一下。使这项工作。

    1. 使用 RequestContext 和 @ensure_csrf_cookie 确保 csrf 令牌实际发送到您打算使用它的页面

    2. 确保 {% csrf_token %} 在您的表单中的某个位置

    3. 将此处的 AJAX 特定代码:https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax 添加到您的页面 JavaScript

    4. 确保通过以下方式将中间件令牌与 ajax 数据一起发回:

      $.ajax({ 网址:“...”, 类型:“发布”, 数据类型: ”...”, 数据: { csrfmiddlewaretoken: csrftoken, ... },

    应该这样做。

    【讨论】:

      猜你喜欢
      • 2023-03-18
      • 2016-05-14
      • 2011-08-04
      • 1970-01-01
      • 1970-01-01
      • 2014-09-23
      • 1970-01-01
      • 2011-05-12
      • 2017-10-12
      相关资源
      最近更新 更多