无法以其他方式查看pdf.js和受保护的文件

pdf.js and protected files not otherwise viewable

提问人:Ben Cahan 提问时间:4/23/2017 更新时间:4/24/2017 访问量:1403

问:

我正在使用 PDF.js 库在我的站点中显示 PDf 文件(使用pdf_viewer.js在屏幕上显示文档),但我显示的 PDF 文件是机密的,我需要能够在站点内显示它们,但阻止未经授权的公众人员只需输入 URL 并看到它们直接显示在他们的浏览器中即可查看相同的文件。

我试图在我的htaccess文件中添加Deny from all行,但是courfse也阻止了查看器显示文档,所以这似乎是不行的。显然,任何人都可以简单地查看检查器并查看查看器正在读取的 pdf 文件,因此直接 URL 似乎在任何方面都不会安全。

我确实读过PDF.js能够读取二进制数据的信息,但我不知道如何在我自己的文件系统中读取 PDF 并准备它以供库使用,如果这意味着加载速度有点慢,以获取文件内容并即时准备它。

有人有解决方案允许PDFJS在不泄露源PDF URL的情况下工作,或者使用本地文件调用读取文件吗?

文件 PDF Base64 pdf.js

评论

0赞 4/23/2017
有什么代码要提供吗?
0赞 Ben Cahan 4/24/2017
好吧,从pdf.js代码:* @param {string|TypedAray|object} source 可以是 PDF 所在的 url、已填充数据的类型化数组 (Uint8Array) 或 * 和具有以下可能字段的参数对象: * - url - PDF 的 URL。* - data - 包含 PDF 数据的类型化数组。* - httpHeaders - 基本身份验证标头。* - password - 用于解密受密码保护的 PDF。 显然,传入 URL 会向外界公开该 URL,但我不清楚如何将 PDF 文件转换为指定的类型化数组。
0赞 Ben Cahan 4/24/2017
显然,如果我可以私下读取 PDF 文件,然后将其转换为 PDFJS 库可用的内容,那么我就可以使用 URL 来绕过 Inspector 的 Network 选项卡中显示的 URL,打开和读取、转换和传回要使用文件屏蔽名称显示的数据。
0赞 async5 4/24/2017
PDF具有密码保护功能--使用它,例如为每个文档生成唯一的密码并在客户端解密

答:

0赞 Ben Cahan 4/24/2017 #1

好的,经过一些测试,解决方案非常简单:

使用 Ajax 调用的函数获取 PDF 数据,该函数可以确定要查看的实际文件。 在那个PHP文件中... 将文件读入内存,正常使用 fopen 和 fread。 使用 base64_encode 转换为 base64 将该字符串传递回调用的 Javascript。

在原始调用函数中,使用以下命令将字符串转换为 Uint 数组,然后将其传递给 PDFJS 库...

## The function that turns the base64 string into whatever a Uint8 array is...
function base64ToUint8Array(base64) {
  var raw = atob(base64);
  var uint8Array = new Uint8Array(raw.length);
  for (var i = 0; i < raw.length; i++) {
    uint8Array[i] = raw.charCodeAt(i);
  }
  return uint8Array;
}

## the guts that gets the file data, calls the above function to convert it, and then calls PDF.JS to display it
$.ajax({
type: "GET",
data: {file: <a file id or whatever distinguishes this PDF>},
url: 'getFilePDFdata.php',  (the PHP file that reads the data and returns it encoded)
success: function(base64Data){
      var pdfData = base64ToUint8Array(base64Data);
      ## Loading document.
      PDFJS.getDocument(pdfData).then(function (pdfDocument) {
       ## Document loaded, specifying document for the viewer and
       ## the (optional) linkService.
      pdfViewer.setDocument(pdfDocument);
      pdfLinkService.setDocument(pdfDocument, null);        
    });
   }
});

评论

0赞 async5 4/24/2017
base64 在 PHP 和浏览器端占用了巨大的内存,每使用一个字节额外 2.5 个字节(您可以注意到 base64ToUint8Array 函数将一次为 base64 分配 2.5*n、行分配 2*n、为 uint8Array 字节分配 n - 总共 5.5*n 个您仅使用 fetch() 或 XHR+arraybuffer 即可获得的内容)
1赞 async5 4/24/2017
re:protection,在ajax/之后设置断点并在控制台中键入会将数据保存在下载文件夹中,不是吗?window.open('data:;base64,'+base64Data)