本文目录导读:

- 传输层安全(HTTPS)
- 身份认证与授权(Authentication & Authorization)
- 入参校验与过滤
- 访问频率限制(限流/防暴力破解)
- 敏感数据脱敏与加密
- 日志与监控
- 其他高级防范措施
- 推荐的安全措施组合流程
PHP 接口安全是 Web 开发中非常重要的一个环节,为了保证接口安全,需要从传输层、认证层、参数层、业务层等多个维度进行防护。
以下是 PHP 接口安全的核心保障策略及代码示例:
传输层安全(HTTPS)
这是最基本的安全保障,防止数据在传输过程中被窃听或篡改。
- 必须使用 HTTPS:对接口进行全站加密,避免敏感数据(如密码、Token)以明文传输。
- 禁用不安全的加密协议:禁止使用 SSLv3、TLSv1.0 等老旧协议。
身份认证与授权(Authentication & Authorization)
确认“你是谁”以及“你能做什么”。
A. 基于 Token 的认证(推荐)
使用 JWT 或自定义 Token,避免使用 Session(Session 在分布式环境下难以共享,且易受 CSRF 攻击)。
<?php
// 生成 Token 示例(使用 JWT 概念简化)
// 实际生产建议使用知名库如 firebase/php-jwt
function generateToken($userId, $secretKey) {
$header = json_encode(['typ' => 'JWT', 'alg' => 'HS256']);
$payload = json_encode([
'user_id' => $userId,
'iat' => time(), // 签发时间
'exp' => time() + 3600 // 1小时后过期
]);
$base64Header = base64_encode($header);
$base64Payload = base64_encode($payload);
$signature = hash_hmac('sha256', "$base64Header.$base64Payload", $secretKey, true);
return "$base64Header.$base64Payload." . base64_encode($signature);
}
// 验证 Token 中间件逻辑
function verifyToken($token, $secretKey) {
$parts = explode('.', $token);
if (count($parts) !== 3) return false;
[$base64Header, $base64Payload, $signature] = $parts;
$expectedSignature = hash_hmac('sha256', "$base64Header.$base64Payload", $secretKey, true);
if (!hash_equals(base64_encode($expectedSignature), $signature)) return false;
$payload = json_decode(base64_decode($base64Payload), true);
if ($payload['exp'] < time()) return false; // 过期
return $payload;
}
?>
B. 接口签名(防篡改)
用于第三方开放平台(如微信支付、支付宝),防止请求参数被中途篡改。
- 将参与签名的参数按字典序排序。
- 拼接成字符串,加上
SecretKey后 MD5 或 SHA256 加密。 - 服务端用同样的规则计算签名,对比传入的
sign是否一致。
<?php
// 生成签名
function generateSign($params, $secretKey) {
ksort($params); // 按key排序
$str = '';
foreach ($params as $k => $v) {
if ($k !== 'sign' && $v !== '' && $v !== null) {
$str .= $k . '=' . $v . '&';
}
}
$str = rtrim($str, '&');
return md5($str . $secretKey);
}
// 服务端校验签名
$requestParams = $_GET; // 或 $_POST
$requestSign = $requestParams['sign'];
unset($requestParams['sign']);
$mySign = generateSign($requestParams, 'your_secret_key');
if (!hash_equals($mySign, $requestSign)) {
exit(json_encode(['code' => 401, 'msg' => '签名错误']));
}
?>
入参校验与过滤
严格校验输入,防止 SQL 注入、XSS 攻击。
- 参数类型强校验:使用
filter_var或正则表达式严格校验类型(如 ID 必须是正整数)。 - 防止 SQL 注入:严禁拼接 SQL,一律使用 PDO 预处理语句 或 Laravel/ThinkPHP 的查询构造器。
- 防止 XSS:对 HTML 标签进行转义(
htmlspecialchars)。
<?php
// 严格校验 ID 必须是正整数
$id = $_GET['id'];
if (!filter_var($id, FILTER_VALIDATE_INT, ['options' => ['min_range' => 1]])) {
exit(json_encode(['code' => 400, 'msg' => '无效的ID']));
}
// PDO 预处理防止 SQL 注入
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id AND status = 1");
$stmt->execute([':id' => $id]);
?>
访问频率限制(限流/防暴力破解)
防止恶意攻击者刷接口,防止暴力破解密码。
- 同一 IP 限制访问次数:如每分钟不超过 60 次。
- 用户维度的限制:如登录接口,同一账号 1 小时只能失败 5 次。
- 实现方式:Redis 计数器或专业的网关(如 Nginx + Lua)。
<?php
// 使用 Redis 实现简易限流
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$key = 'login_fail:' . $_POST['username'];
$count = $redis->get($key);
if ($count !== false && $count >= 5) {
exit(json_encode(['code' => 429, 'msg' => '尝试次数过多,请1小时后再试']));
}
// 登录验证逻辑(失败时计数)
?>
敏感数据脱敏与加密
- 密码:绝对不能用 MD5,使用
password_hash()和password_verify()。 - 接口返回数据脱敏:手机号、身份证号在返回给前端时进行掩码处理(如
138****1234)。
日志与监控
- 记录关键操作日志:记录 IP、User-Agent、请求参数(密码除外)、请求时间、响应时间。
- 异常监控:利用 Sentry 等工具实时监控异常报错,防止敏感信息泄露在日志中。
其他高级防范措施
- 签名防重放攻击:在签名参数中加入
nonce(随机数)和timestamp(时间戳),服务端将已使用的nonce存入 Redis,设置过期时间(如 5 分钟),5 分钟内相同nonce再次请求则拒绝。 - CSRF 防护:非
GET请求必须携带X-CSRF-Token请求头,且该 Token 与用户 Session 绑定。 - 框架辅助:使用 Laravel / Symfony 等成熟框架,框架自带的安全防护(中间件、ORM 防注入、验证管道)比手写更完善。
推荐的安全措施组合流程
graph TD
A[客户端发起请求] --> B[检查 IP 黑名单/限流]
B --> C[验证 HTTPS/TLS 证书]
C --> D[验证接口签名 Sign 防篡改]
D --> E[验证身份 Token 是否有效]
E --> F{是否授权访问该资源?}
F -- No --> G[返回 403 禁止访问]
F -- Yes --> H[业务处理前进行参数白名单校验]
H --> I[执行业务逻辑(PDO 预处理防注入)]
I --> J[记录操作日志]
J --> K[返回数据并进行敏感字段脱敏]
PHP 接口安全没有“一键开启”的魔法,而是一套纵深防御体系,对于中小型项目,足够重视 HTTPS、参数校验、Token 认证和日志记录这四点,通常能解决 80% 的安全问题,对于高价值业务(如支付接口),则必须加上签名防篡改、防重放攻击和严格的频率限制。