【问题标题】:Safely hiding PDF-invoices on a website using PHP使用 PHP 在网站上安全隐藏 PDF 发票
【发布时间】:2012-11-02 22:08:35
【问题描述】:

我正在制作一个网站,人们可以在其中注册参加沙滩排球假期。该网站没有在线支付,所以它的工作原理是人们自己注册(在一个好的 ol' html 表单上),然后你会收到一封电子邮件,其中应该包含发票。我已经做到了,所以这张发票是使用 FPDF 生成的(http://www.fpdf.org/ - 尽管我认为这对于这个问题的答案并不重要)。所以 FPDF 需要一堆 PHP 变量并用它制作一个 PDF 文件,并将这个文件放在 FTP 服务器上的一个目录中。

现在,我可以看到从服务器获取此发票给刚注册的人的两种方法(因为他们会立即想要它以确认他们的注册):

1) 将其附加到电子邮件中(我已经尝试了大约一个小时并且可以做到)。如果这是更好的选择 - 那我该怎么做?上次尝试时,我淹没在一堆我以前从未听说过的关于 MIME 的信息中。这是正确的轨道,还是有更简单的方法?我还阅读了一些有关 Zend_framework 和 PHPMailer 的内容,但并不真正知道哪种方法是正确(或更好)的方法......

或者...

2) 在电子邮件中添加发票链接。现在,如果我这样做,那么 URL 应该以某种方式被屏蔽或加密,因为如果他们访问的链接是:

http://www.something.com/invoicefolder/invoice16.pdf

显然,人们可以将 16 更改为 15,突然之间,那些掌握网络知识的人就可以访问所有发票。

这就是为什么我谦虚地问你,StackOverflow... 将这张发票从 FTP 服务器发送到通信方法是电子邮件的客户端,最好(或最安全的方式)是什么?

谢谢。

【问题讨论】:

    标签: php email attachment email-attachments


    【解决方案1】:

    我会查看 PHPMailer 并将发票作为附件发送。 PHPMailer 非常易于使用,并且有一些很棒的示例代码。

    【讨论】:

      【解决方案2】:

      只需确保发票不在公用文件夹中(即在 doc 根目录下),并让 PHP 根据请求为它们提供服务。这样您就可以强制人们登录。

      另一个需要是只将发票附加到电子邮件中,尽管人们往往会丢失电子邮件并且他们仍然希望能够访问他们的发票。

      【讨论】:

        【解决方案3】:

        你必须创建一个控制器文件,比如“invoice.php”,它会强制下载指定的pdf文件,你的url应该是这样的

        假设您在 invoices 文件夹中存储了一个文件 54219683.pdf,您可以在电子邮件中发送以下 url

        http://www.example.com/invoice.php?id=54219683

        这是一个非常简单的例子

        //file: invoice.php
        //content type
        $file = $_GET['id'].'.pdf';
        header('Content-type: application/pdf');
        //open/save dialog box
        header('Content-Disposition: attachment; filename="$file"');
        //read from server and write to buffer
        readfile($file);
        

        您可以在http://www.finalwebsites.com/forums/topic/php-file-download找到更多通过php文件下载pdf的详细信息

        您不应保存与数据库 ID 精确映射的实际文件,但应为每个发票文件名使用一个随机的唯一编号,该编号不能被黑客猜到。

        当您使用序列号保存文件时会出现问题,因此不要保存您的 pdf 文件,例如 1.pdf、2.pdf、3.pdf,而是使用随机数保存,其次不要发送带有确切 url 的电子邮件文件,但通过控制器文件下载,您可以在其中添加更多限制,还可以跟踪每次下载。

        【讨论】:

          【解决方案4】:

          我淹没在一堆我以前从未听说过的关于 MIME 的信息中

          很抱歉,但这确实让我敲响了警钟 - 您必须对在代码中实现解决方案所涉及的技术有基本的了解。

          是的,您可以将其附加到电子邮件中 ​​- 但是我建议您在对软件开发更加熟悉之前不要使用 zend 框架。 phpmailerswiftmailer 都提供了一个简单的、有据可查的 API 来处理电子邮件中的附件。

          解决该问题的一个简单方法是将 PDF 文件保留在文档根目录之外,并使用代理脚本执行附加验证。例如

          define('MY_SECRET', 'some rAnd0m strlng');
          define('DOC_DIR','/path/to/files');
          
          function getIdHash($id)
          {
             return sha1($id . MY_SECRET);
          }
          
          $id=(integer) $_GET['doc_id'];
          $filename=DOC_DIR . '/' . $id . '.pdf';
          if ( ($_GET['chk']==getIdHash($id)) 
              && file_exists($filename) && is_readable($filename)) {
             header("Content-type:application/pdf");
             readfile($filename);
             exit;
          } else {
             header("Status: 404 Not Found");
             print "Document does not exist or not authorized";
          }
          

          【讨论】:

            【解决方案5】:

            我会采用类似于 RapidShare 等共享储物柜的方案:

            domain.com/invoice/{md5($email)}/{time()}.pdf
            

            此解决方案足够隐蔽以确保安全。有人很难猜测(或暴力破解)电子邮件地址的 MD5 摘要和生成发票的时间。

            此外,您可以发送带有附件的电子邮件,就像其他人所说的那样,如果您使用像 SwiftMailer 这样的库,这非常简单。即使implementing your own 也没有那么难。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2016-04-20
              • 1970-01-01
              • 1970-01-01
              • 2017-02-03
              • 1970-01-01
              • 2012-12-16
              • 1970-01-01
              相关资源
              最近更新 更多