2011-07-30 80 views
0

我希望用户看到图像作为网页的一部分我想避免他们直接访问图像。这可以说,在URL中提供了关于他们链接到的用户的线索(我在一个Facebook应用程序中看到的一个缺陷)。监视图像访问和/或阻止直接访问

我该如何去监控图像访问和/或防止直接访问图像(通过url重写,例如...)?

解决方案提出至今:

  • 使用头(可靠?)
  • 进行访问图像更加困难(例如:一套图像作为背景的div)。
  • ...
+2

您可以检查引用者标​​题;如果图片是从您的网站加载的,则引荐来源应该是您网域上的网址。虽然这并非万无一失,但某些广告拦截/隐私软件和代理服务器会剥离引荐标头,使其看起来像直接访问,而不是。 –

+1

使图像成为div的背景 - 用户获得直接链接(但可能)会更困难。 –

+0

检查引荐来源的方法是错误的。推荐人可以是空的,甚至可能是错误的(前一页的网址,不是最新的)。 –

回答

3

没有防弹的方法。但是,您可以使用启发式。检查以下标题:

  1. Referer - 此标头将存在是由浏览器作为<img>标签或CSS的结果所要求的图像。如果直接请求图片(通过在地址栏中输入网址),此标题将为空。如果此标题包含另一个域名,那么该另一个网站将您的图片热链接起来。 请注意,这是预期的行为,但不能保证每个浏览器都会以这种方式行事。

  2. Accept - 这头将包含一个字符串,如image/*当请求图像,因为浏览器发现它嵌入在HTML标记或CSS。当有人通过在浏览器中输入直接请求图片时,您会发现诸如text/html,application/xhtml+xml等的值。这是因为浏览器在请求时不知道该期待什么http://website.com/someimage.jpg;因此它最好要求text/html内容。

在Apache中,您可以检查(并匹配)HTTP头以确定内容是否可访问。我不确定其他平台,但您可以编写通用代理脚本来提供图像。

编辑

如果图像URL表明你不想披露的信息,您可以通过使用哈希值或加密混淆了。因此,而不是服务内容,如:

<img src="/images/users/12345.jpg"> 

你会写:

<img src="/images/users/image.php?hash=<?php echo md5('secret' . '12345'); ?>"> 

你需要编写发送相应的图像浏览器的脚本。

+0

downvote的原因? –

+0

'因为浏览器不知道什么时候它会要求http:// website.com/someimage.jpg' - 大声笑,哪个浏览器是如此愚蠢的不读取URL中的'.jpg'?而你的第一个关于引用链接的“规则”是完全错误的。推荐人可以是空的或可以包含另一个域...只是因为(你可以检查它)。这个头的行为是非常不可预测的。 –

+0

@SalmanA:当你右击并点击“显示图像”时,它也会“发送”引用者 – genesis

1

如果可以的话,那再一次不是防弹的,但招数很多的是用图像作为背景。在你的HTML中放置一个图像标签,填充一个特殊的透明1px乘1px gif(blank.gif大约为html表格布局),并将其大小设置为实际图像的尺寸。然后将其背景图像设置为实际图像。这将欺骗许多只知道如何右键点击下载/获取图像URL的用户。

<html> 
<head> 
    <style> 
     #logo { background: url(my-logo.png); width: 100px; height: 50px; } /* Change this to match your image name and dimensions */ 
    </style> 
</head> 
<body> 
    <img src="blank.gif" id="logo"> 
</body> 
</html> 

我知道这不会帮助,如果用户打印屏幕(但也不会任何方法),但它是为那些懂行的少用户的解决方案。另外,像Youtube这样的网站已经采用了这种方法,所以如果它足够Google的话,我会说这对你或我来说已经足够了!

编辑:请原谅我完全没有意识到这已被张贴为评论。在我发布之前,我开始写作。

1

至于说,没有这样做银弹(你不能阻止用户进行例如屏幕截图)

但是,如果你想保护你的照片对匿名访问,你可以使用一个PHP的“代理”,将检查用户是否被允许看到该图片,然后加载它。

这是一个非常简单的代码示例代码。 如果您确实想保护您的图片,请将它们存储在文档根目录之外。

<?php 

//Sample image protection proxy. Do not use as is. 

//Let's monitor the authorized accesses 
session_start(); 
$mon = isset($_SESSION['mon']) ? $_SESSION['mon'] : 0; 


//Let's simulate an auth mecanism 
$allowed = isset($_GET['allowed']) ? (int)$_GET['allowed'] : 0; 

if ($allowed === 1) { 
    // DO NOT USE AS IS ! add security checks to prevent XSS, especially if images are uploaded by untrusted users 
    $img = file_get_contents('img.png'); 
    $mon++; 
    $_SESSION['mon'] = $mon; 
    header('content-type:image/png'); 
    echo $img; 
} else { 
     //handle unauthorized access here. 
    //For this example, I send some plain text 
    header('content-type:text/plain'); 
    echo 'You are not allowed to see that picture.'.PHP_EOL; 
    echo 'This picture has been opened : '.$mon. ' times.'; 
} 
?> 

如果你想测试这个脚本:

  • 把它放在你的文档根
  • 在同一个文件夹中添加PNG图像。将此图像命名为img.png。
  • 要访问图像,请使用http://url/of/the/script.php?allowed=1
  • 访问计数器,删除'允许'变种。

希望有帮助!

1

这里有一个想法,可能工作,但我没有真正想通了太多,还没有尝试过:

  1. 服务器收到一个页面的请求。
  2. 使用引用图像的一次性密钥(OTK)在PHP中生成页面内容。 OTK可以存储在会话变量或数据库中。
  3. 当客户端呈现页面时,服务器使用OTK通过查询参数为图像接收请求。提供图像并删除OTK。

例如,而不是:

<img src="www.mysite.com/mypage/myimage.jpg">

...生成的一次性密钥和存储在一个查找表,以便它指的是你的形象:

4e33fd162fe95 => image.jpg

...然后使用生成的页面,而不是OTK:

<img src="www.mysite.com/mypage?image=4e33fd162fe95">

当服务器收到对该图像的请求时,发送图像并删除OTK。这意味着每个页面请求都会生成一个新的OTK。试图再次使用该URI的图像将无法正常工作。

这在性能方面有一些明显的警告,因为客户端缓存将不再起作用,并且会在服务器上产生一些开销。也可能有其他警告。