2

我刚刚发现一个奇怪的问题,我使用 tornado 来运行我的网站,并且在 tornado POST 中需要 _xsrf 参数,以下代码在我使用 jQuery 版本 1.7.2 时运行良好,但是当我重新打开浏览器时出现 POST 403 错误(保留 cookie活着) 在我将 jQuery 更改为 1.8.3 版本之后...但是 1.7.2 和之前的版本可以正常工作...

龙卷风中的 403 表示 _xsrf 不正确。关键是当我重新打开浏览器时发生 403 错误,我仍然登录但无法 POST。

有人知道问题吗?以下是代码

        function getCookie(name) {
                var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
                return r ? r[1] : undefined;
        }

        jQuery.postJSON = function(url, args, callback) {
                    args._xsrf = getCookie("_xsrf");
                    $.ajax({
                                url: url, data: $.param(args), dataType: "text", type: "POST", async: true,
                                success: function(response) {
                                    if (callback) callback(eval("(" + response + ")"));
                                }, 
                                error: function(response) {
                                    try{
                                        args._xsrf = getCookie("_xsrf");
                                        $.ajax({url: url, data: $.param(args), dataType: "text", type: "POST", async: true,
                                            success: function(response) {
                                                if (callback) callback(eval("(" + response + ")"));
                                            }
                                        });
                                    }
                                    catch(e){

                                    }
                                }
                    });
        };
4

1 回答 1

3

我有同样的问题。出于某种原因,浏览器重新启动后,'_xsrf' 值会从 cookie 中删除。问题是,为什么龙卷风不再设置这个cookie?查看龙卷风代码(web.py):

    token = (self.get_argument("_xsrf", None) or
             self.request.headers.get("X-Xsrftoken") or
             self.request.headers.get("X-Csrftoken"))
    if not token:
        raise HTTPError(403, "'_xsrf' argument missing from POST")
    if self.xsrf_token != token:
        raise HTTPError(403, "XSRF cookie does not match POST argument")

我们可以看到,如果在请求的任何地方都没有找到 _xsrf,那么请求会立即被拒绝。新的 cookie 值将在行设置

    if self.xsrf_token != token:

没有达到(self.xsrf_token 是一个函数,用@property 包装)。

因此,最简单的解决方法是:

  1. 更改函数 getCookie 以在 cookie 中找不到 _xsrf 的情况下返回一些字符串。例如'not_found':

    function getCookie(name) {
        var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
        if (!r && name == "_xsrf"){
            return 'not_found'
        }
        return r ? r[1] : undefined;
    }
    
  2. 现在,在第一个错误请求之后,tornado 将设置 _xsrf cookie。第二个请求将通过

另一种解决方案:

每次在龙卷风中呈现页面时,self.xsrf_token请点击请求处理程序中的属性。所以你可以确定,'_xsrf' cookie 已设置。

于 2013-01-29T18:04:39.623 回答