仅在成功提交表单时提供PDF

时间:2016-05-26 19:32:04

标签: angularjs node.js security pdf

设置MEAN堆栈应用程序以仅在成功完成表单时下载PDF附件的最简单方法是什么?

注意:没有用户管理。每个人都可以查看此表单。如果他们成功填写,他们应该能够下载表格。但是,我们不希望URL在电子邮件中可共享。获取PDF的唯一方法是填写表单。 (当然,PDF可以通过电子邮件发送给任何人,但这很好。)

目前,只能通过访问NodeJS / express端点来下载PDF,如下所示:

(?: ... )?

直接无法公开访问/ pdf。

关于如何做到这一点的一些想法:

  1. 网站的每个访问者都会收到一个特殊密钥,如果他们正确填写表格,访问'/ specialkey'将成为下载电子书的临时终端。然后在客户端中,将执行app.get('/endpoint', function(req, res) { res.setHeader('Content-disposition', 'attachment;'); res.setHeader('Content-type', 'application/pdf'); var file = __dirname + '/pdf/ebook.pdf'; res.download(file); }); 以下载电子书。
  2. 但是,我不确定将密钥发送给每个唯一用户的最佳方法是什么。而且,对于概念上简单的东西来说,它似乎过于复杂。 “仅在成功提交表格时提供电子书。”

    有没有人遇到过这个?

    SOLUTION:

    服务器:

    $window.location.assign('/specialkey');

    客户端:

    var session = require('express-session');
    
    ...
    
    app.use(session({
        secret: 'your secret here',
        name: 'your session name here',
        proxy: true,
        resave: true,
        saveUninitialized: true
    }));
    
    ...
    
    // Send the session ID to the client
    app.get('/key', function(req, res) {
        res.send(req.session.id);
    });
    
    // Download PDF
    app.get('/download/:token', function(req, res) {
        if (req.params.token === req.session.id) {
            res.setHeader('Content-disposition', 'attachment;');
            res.setHeader('Content-type', 'application/pdf');
            // Note: /pdf directory is not publicly accessible 
            var file = __dirname + '/pdf/ebook.pdf';
            res.download(file);
        } else {
            res.sendFile(__dirname + '/public/index.html');
        }
    });
    

1 个答案:

答案 0 :(得分:1)

成功发布表单以生成令牌文档后(在此答案中我假设您使用mongo)并只使用键导航到url:

window.location.href = '/download/sometokenhere';

并在服务器端:

app.get('/download/:token', function(req, res) {
    // for example we use mongodb with mongoose
    TokenModel
     .find({token: req.params.token})
     .count()
     .exec(function(err, count) {
        if(err || parseInt(count) == 0) {
          return res.redirect('/');
          // or: return res.status(403).send('Forbidden');
        } 

        res.setHeader('Content-disposition', 'attachment;');
        res.setHeader('Content-type', 'application/pdf');
        var file = __dirname + '/pdf/ebook.pdf';
        res.download(file);
      });
});

或您可以设置:

req.session.downloadToken = md5(new Date().getTime());

并在下载路线中检查令牌是否等于:

req.session.downloadToken

有很多方法......

另一种方式是当表单没问题然后返回带有downloadLink的json响应,然后导航到将被视为要下载的文件的URL。