php 实现防盗链
PHP 实现防盗链的方法
防盗链(Hotlink Protection)可以防止其他网站直接引用你的资源(如图片、视频等),从而节省带宽并保护内容版权。以下是几种常见的 PHP 实现方法:
检查 HTTP Referer
通过检查 $_SERVER['HTTP_REFERER'] 来判断请求是否来自合法域名。如果不是,则拒绝访问或返回错误信息。
$allowed_domains = ['example.com', 'trusted-site.com'];
$referer = $_SERVER['HTTP_REFERER'] ?? '';
if (!empty($referer)) {
$referer_host = parse_url($referer, PHP_URL_HOST);
if (!in_array($referer_host, $allowed_domains)) {
header('HTTP/1.1 403 Forbidden');
exit('Access denied - Hotlinking not allowed');
}
} else {
// 允许直接访问或根据需求处理
}
使用 .htaccess 文件配合 PHP
在 Apache 服务器中,可以通过 .htaccess 文件结合 PHP 实现防盗链:
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?example\.com/ [NC]
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?trusted-site\.com/ [NC]
RewriteRule \.(jpg|jpeg|png|gif|mp4)$ - [NC,F,L]
如果需要在 PHP 中动态处理,可以将非法请求重定向到 PHP 脚本:
RewriteRule \.(jpg|jpeg|png|gif|mp4)$ /anti-hotlink.php [NC,L]
然后在 anti-hotlink.php 中处理:
header('HTTP/1.1 403 Forbidden');
exit('Hotlinking not allowed');
动态生成资源链接
通过 PHP 动态生成资源链接,并在 URL 中加入 token 或时间戳验证:
// 生成带 token 的链接
$token = md5('secret-salt' . $file_path . time());
$image_url = "download.php?file=" . urlencode($file_path) . "&token=" . $token;
// 在 download.php 中验证
$file = $_GET['file'] ?? '';
$token = $_GET['token'] ?? '';
$expected_token = md5('secret-salt' . $file . time());
if ($token !== $expected_token) {
header('HTTP/1.1 403 Forbidden');
exit('Invalid token');
}
// 输出文件
header('Content-Type: image/jpeg');
readfile($file);
使用会话(Session)验证
如果是用户私有资源,可以通过 Session 验证用户权限:
session_start();
if (!isset($_SESSION['user_id'])) {
header('HTTP/1.1 403 Forbidden');
exit('Login required');
}
// 输出文件
header('Content-Type: image/jpeg');
readfile($file_path);
返回替代内容
对于图片等资源,可以检测非法引用后返回替代内容(如水印图片或提示信息):
$referer = $_SERVER['HTTP_REFERER'] ?? '';
if (!empty($referer) && !str_contains($referer, 'example.com')) {
header('Content-Type: image/jpeg');
readfile('watermark.jpg');
exit;
}
// 正常输出原图
header('Content-Type: image/jpeg');
readfile($original_image);
Nginx 防盗链配置
如果使用 Nginx,可以在服务器配置中直接实现:

location ~* \.(jpg|jpeg|png|gif|mp4)$ {
valid_referers none blocked example.com trusted-site.com;
if ($invalid_referer) {
return 403;
}
}
注意事项
HTTP_REFERER的可靠性:部分浏览器或代理可能不发送 Referer,需根据业务需求处理空值情况。- CDN 兼容性:如果使用 CDN,需确保 CDN 支持防盗链配置或传递 Referer。
- 性能优化:动态生成资源链接会增加服务器负载,建议结合缓存机制。
以上方法可根据实际需求组合使用,例如同时检查 Referer 和动态 token。






