phantomjs - 如何在 phantomJS 中正确添加 csrf token

标签 phantomjs

我想在 phantomJS 中获取 pdf 格式的网站内容,这很容易,如 phantomJS 文档中所述

phantomjs rasterize.js 'http://en.wikipedia.org/w/index.php?title=Jakarta&printable=yes' jakarta.pdf

到目前为止一切顺利。我现在的问题是,我想要打印为 pdf 的网页需要用户登录并发布包含 2 个输入字段的表单!输入字段是开始日期和结束日期,生成所需网站的结果,稍后将打印为 pdf。该网站是用 Django 编写的,默认情况下需要 csrf token 。我编写的这段代码不起作用,即使可以,也对我没有帮助,因为我无法在光栅化的帮助下使用它来将页面内容转换为 pdf。

"use strict"
var page = require('webpage').create(),
    server = 'http://10.0.3.201:8000/report/',
    data = 'start_date=23.03.2016&end_date=24.03.2016';

page.settings.userName = 'ubuntu';
page.settings.password = 'ubuntu';

page.includeJS(
    // Include the http version, you can change this to http if you like.
    'https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js',
    function() {
        (page.evaluate(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;
        }
        phantom.addCookie({
            'name'      : 'csrf',
            'value'     : getCookie('csrftoken'),
            'domain'    : 'localhost',
            'path'      : 'report',
            'httponly'  : true,
            'secure'    : false,
            'expires'   : (new Date()).getTime() + (1000 * 60 * 60)
        });
        )
    }
);

page.open(server, 'post', data, function(status) {
    if (status !== 'success') {
        console.log('Unable to post!');
    } else {
        console.log(page.content);
    }
    phantom.exit();
});

我非常无能,甚至不知道我想做的事情是否可以用 phantomJS 实现。非常感谢您的帮助!

最佳答案

Django 在每个 GET 中使用 csrf token 设置一个 cookie(如果在 POST 模板中配置,则在表单内的 DOM 中),但此 cookie 不用于验证服务器中的 POST 请求(这将导致安全漏洞)。

Django 似乎从标准 POST 正文(表单数据)或名为 X-CSRFToken 的自定义 HTTP header 读取 csrf token 。

因此,要伪造有效的请求,您必须模拟标准用户交互:

  • 对为您需要的 POST 创建 csfr token 的页面进行 GET(可以是 autopostback 中的同一页面或 FormAction="postDestination"的另一个页面)。此响应将在 Form DOM 和 cookie 中附带一个 csrf token 。
  • 从 cookie 或 DOM 获取 csrf token
  • 伪造一个有效的 POST 请求,并在表单数据请求和/或自定义 header 中设置 token 。
  • 您应该收到可以呈现为 pdf 格式的成功响应。

如果 rasterize.js 不允许上述任何步骤,您将需要创建自定义 rasterize.js。

无论如何,您的 POST 似乎没有修改系统中的任何内容,它看起来像一个搜索,所以我认为您可以仅针对此 POST 禁用 csrf。

关于phantomjs - 如何在 phantomJS 中正确添加 csrf token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36280051/

相关文章:

node.js - 运行目录中的所有 'test.html' 文件 - mocha-phantomjs

javascript - 如何用 selenium 更改 phantomjs 的日志文件路径?

node.js - 如何使用带有 Request-promise 的自定义 cookie 发送请求

javascript - PhantomJS - 上传文件而不提交表单

javascript - Phantomjs 和 HTML 5 触发点击事件并提交表单失败

javascript - PhantomJS 屏幕截图 D3.js 数据图

javascript - 在 Windows 中需要 .js 文件

javascript - PhantomJS 导航页面和完整的工作流程

phantomjs - 如何在 CasperJS/PhantomJS 脚本中与用户交互?

jquery - 如何在 phantomJS 中执行 jQuery promise ?