【问题标题】:Is it possible to reliably know where an HTTP request originated without scripting?是否可以在不编写脚本的情况下可靠地知道 HTTP 请求的来源?
【发布时间】:2011-08-08 01:48:31
【问题描述】:

我的任务是从我们的服务器提供一个图像文件,该文件在驻留在许多其他服务器上的 html 文档中引用。也就是说:

foo.com 上的文件:
<img src='http://bar.com/image.jpg'>

当用户访问 foo.com 时,它会显示来自我们服务器 bar.com 的图像。 (它实际上会根据发出请求的网站发送不同的图像。)

但问题是:他们只希望特定公司的访问者能够检索文件(当前由服务器的域名标识,但这不是必需的)。

在理想情况下,您只需查看 HTTP_REFERER,如果它在批准列表中,则提供文件。但众所周知,并非每个用户代理都提供 HTTP_REFERER,而且无论如何都可能被欺骗。

最好不必运行 javascript 或 php,但我们所追求的甚至可能在没有脚本的情况下实现吗?

如果没有,有没有办法只使用 javascript 以使其他网站无法通过欺骗方式下载文件?

如果没有,您将如何使用 PHP 来处理它?

【问题讨论】:

  • 您说的是网站下载文件?文件由客户端在浏览器中下载,而不是由网站下载。每个 HTTP 请求,无论是针对页面、脚本、图像等,都是一个单独的请求,来自用户的浏览器,而不是他们正在浏览的网站。
  • 仍然可以进行服务器到服务器的下载。但听起来 OP 只是想问“什么是验证下载的好方法”
  • 是的,我知道用户代理会进行下载,但最终的问题是它们不能被 HTTP_REFERER 信任。我不想要经过身份验证的下载;我希望“白名单”服务器的任何公共用户都能够查看图像,但不能查看其他服务器。

标签: php javascript http http-headers http-referer


【解决方案1】:

简而言之,没有。您拥有的唯一可靠信息是请求图像的 IP 地址,但即使它也可能是代理。没有可靠的方法来确定在哪个 context 中请求了图像(即图像嵌入在哪个 HTML 页面中)。

您想要的是只允许某些人访问图像。有两种方法可以做到这一点:

  • 如果已知,则通过请求 IP 地址进行过滤
  • 需要经过身份验证的 session/cookie/Authorization 标头,即密码保护图像

如果您的网络服务器支持其中任何一项检查(几乎任何服务器都可以按 IP 过滤请求),则无需编写脚本。对于密码身份验证,您可能必须使用脚本,这取决于它应该如何工作。

(客户端)Javascript 在这里根本没有任何用处。

【讨论】:

    【解决方案2】:

    您对获得批准的公司的网络应用程序有任何影响吗?如果是这样,我可以想出两种方法来实现这一点。

    使用您的 foo/bar 示例,其中 bar.com 是您的服务器,而 foo.com 是您批准的公司之一:

    1) 与其让浏览器向您的服务器发出请求,不如让浏览器向 foo.com 上的图像处理程序发出请求,该处理程序反过来向后台的服务器发出 HTTP 请求并将图像内容返回给客户端。 Foo 的传出 IP 地址将在您服务器的白名单上,因此所有请求实际上都来自 Foo 的 IP 地址。客户会看到:

    <img src="http://foo.com/imagehandler.php" />
    

    2) 困难得多,但是如果 Foo 无法向您的服务器发出请求,Foo 可以在图像标签的查询字符串中放置一个特殊的哈希,这样当浏览器向您的服务器发出请求时,您就会知道该 URL 是由 Foo 构建的。您需要 Foo 的服务器上的私钥,以便它可以计算哈希。

    我猜哈希值会根据浏览器的 IP 地址、当前日期/时间和私钥的组合来计算。

    因此浏览器会向 foo.com/default.php 发出请求,而 Foo 会为浏览器构建以下图像标签:

    <img src="http://bar.com/imagehandler.php?hash=393923A423B423F234C34" />
    

    该数字代表适当的哈希值。在 Bar 的图像处理程序代码中,您需要根据仅 Foo 和 Bar 知道的私钥、作为 GET 请求的一部分的 IP 地址以及当前日期/时间重新计算该哈希值。如果哈希匹配,那么您可以确定浏览器正在查看 foo.com 的网站,并且您可以返回图像内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-05
      • 1970-01-01
      • 1970-01-01
      • 2010-12-23
      • 1970-01-01
      • 2013-01-05
      • 1970-01-01
      相关资源
      最近更新 更多