php实现盗链
实现防盗链的方法
在PHP中实现防盗链(Hotlink Protection)可以通过检查HTTP请求的Referer头部信息,判断请求是否来自允许的域名。以下是几种常见的实现方式:
检查Referer头部
通过检查$_SERVER['HTTP_REFERER'],判断请求来源是否合法:
$allowedDomains = ['example.com', 'trusted-site.com'];
$referer = parse_url($_SERVER['HTTP_REFERER'] ?? '', PHP_URL_HOST);
if (!in_array($referer, $allowedDomains)) {
header('HTTP/1.1 403 Forbidden');
exit('Access denied - Hotlinking not allowed');
}
- 如果
Referer不在白名单中,返回403禁止访问。 - 注意:
Referer可能被伪造或缺失,需结合其他方法增强安全性。
使用.htaccess文件
在Apache服务器中,可以通过.htaccess文件直接实现防盗链:
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^https://(www\.)?example\.com/ [NC]
RewriteCond %{HTTP_REFERER} !^https://(www\.)?trusted-site\.com/ [NC]
RewriteRule \.(jpg|png|gif|mp4)$ - [F]
- 规则会阻止非白名单域名访问图片或视频文件。
[F]表示返回403状态码。
动态生成资源链接
通过PHP动态生成带有令牌(Token)的资源链接,验证合法性:
// 生成加密令牌
$secret = 'your-secret-key';
$file = 'protected-image.jpg';
$expires = time() + 3600; // 1小时有效期
$token = md5($secret . $file . $expires);
// 输出带令牌的链接
echo "<img src='get_file.php?file=$file&token=$token&expires=$expires'>";
在get_file.php中验证令牌:
$secret = 'your-secret-key';
$file = $_GET['file'];
$token = $_GET['token'];
$expires = $_GET['expires'];
if (time() > $expires || $token !== md5($secret . $file . $expires)) {
header('HTTP/1.1 403 Forbidden');
exit('Invalid token');
}
// 输出文件内容
header('Content-Type: image/jpeg');
readfile($file);
使用Nginx配置
在Nginx中可通过valid_referers指令实现:
location ~* \.(jpg|png|gif)$ {
valid_referers none blocked example.com *.example.com;
if ($invalid_referer) {
return 403;
}
}
none表示允许直接访问(无Referer)。blocked允许Referer被防火墙修改的请求。
结合会话验证
对于用户私有资源,可通过会话(Session)验证权限:
session_start();
if (!isset($_SESSION['user_id'])) {
header('HTTP/1.1 403 Forbidden');
exit('Login required');
}
// 输出文件
header('Content-Type: image/jpeg');
readfile('private-image.jpg');
注意事项
Referer检查可能影响SEO或合法引用,需谨慎设置白名单。- 动态令牌会增加服务器开销,但安全性更高。
- 对于静态资源,服务器配置(如.htaccess或Nginx)性能更优。







