PHP场景下:如何阻止人类访问网站但不拦截自身Ajax请求?
如何阻止非法访问Ajax接口但放行合法请求
嘿,这个问题我之前帮不少开发者踩过坑,核心就是要精准区分合法的Ajax请求和用户手动发起的/篡改的请求。下面给你几个实用的方案,按可靠性排序:
1. 强制验证CSRF令牌(最可靠)
这是防御这类问题的标准做法,因为每个合法请求都需要携带服务器生成的唯一令牌,用户手动篡改很难拿到有效令牌。步骤如下:
生成并存储令牌:在用户加载页面时,生成随机令牌存在Session里,同时输出到页面的隐藏字段或全局变量
session_start(); if(!isset($_SESSION['csrf_token'])) { $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); // 生成安全的随机令牌 }页面里输出令牌:
<input type="hidden" id="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">Ajax请求携带令牌:发起请求时,把令牌作为参数或请求头发送(以jQuery为例)
$.ajax({ url: '/your-ajax-endpoint.php', method: 'POST', data: { csrf_token: $('#csrf_token').val(), // 你的其他业务参数 }, success: function(res) { // 处理响应 } });后端验证令牌:在Ajax接口里验证令牌是否匹配Session中的值
session_start(); if(!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) { header("HTTP/1.1 403 Forbidden"); exit("非法请求:无效的CSRF令牌"); } // 验证通过,处理业务逻辑小贴士:可以在每次验证通过后更新令牌,进一步提升安全性。
2. 检查X-Requested-With请求头(辅助手段)
大部分前端框架(jQuery、Axios、Vue-resource等)发起Ajax请求时,会自动添加X-Requested-With: XMLHttpRequest请求头。我们可以在后端检查这个头:
if(!isset($_SERVER['HTTP_X_REQUESTED_WITH']) || strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) !== 'xmlhttprequest') { header("HTTP/1.1 403 Forbidden"); exit("非法请求:仅允许Ajax访问"); }
⚠️ 注意:这个头可以被伪造,所以不能单独使用,要和CSRF令牌搭配。
3. 验证请求来源(补充手段)
通过HTTP_REFERER检查请求是否来自你的网站域名,作为额外的防御层:
$allowed_domains = ['your-domain.com', 'www.your-domain.com']; $referer_host = parse_url($_SERVER['HTTP_REFERER'] ?? '', PHP_URL_HOST); if(!in_array($referer_host, $allowed_domains)) { header("HTTP/1.1 403 Forbidden"); exit("非法请求:来源不被允许"); }
⚠️ 注意:部分浏览器可能不会发送Referer头,所以这个只能作为辅助,不能依赖。
额外建议:后端参数校验
即使通过了上面的验证,也一定要在后端对传入的参数做合法性校验——比如检查参数类型、取值范围、是否符合业务逻辑,不能完全相信前端的限制(毕竟前端很容易被篡改)。
内容的提问来源于stack exchange,提问作者Leon
相关产品推荐
相关产品推荐

