如何保护您的 API 免受未授权访问

如今,API 处理了 71% 的所有 Web 流量,然而 78% 的攻击在通过身份验证后仍然成功。如果您仅依赖 API 密钥或基本身份验证,您的 API 仍然容易受到未授权访问、数据泄露和服务中断的威胁。
本文涵盖了每个开发者都需要了解的基本安全实践:适当的身份验证方法(JWT、OAuth 2.0)、授权控制(RBAC)、速率限制、输入验证、加密以及 API 网关实现。您将学习如何构建协同工作的分层防御体系,以防止未授权访问——即使在攻击者拥有有效凭证的情况下也能有效防护。
核心要点
- 实现 JWT 或 OAuth 2.0,提供超越简单 API 密钥的强大身份验证
- 使用基于角色的访问控制(RBAC)高效管理权限
- 应用速率限制防止滥用和 DoS 攻击
- 针对严格的模式验证所有输入数据,以阻止注入攻击
- 对所有 API 端点强制执行 HTTPS/TLS 加密
- 部署 API 网关实现集中式安全管理
身份验证:您的第一道防线
JWT 身份验证实现无状态安全
JSON Web Tokens (JWT) 提供了适用于分布式系统和微服务的无状态身份验证。与基于会话的身份验证不同,JWT 在令牌本身中包含所有必要信息。
// Generate JWT with proper security claims
const jwt = require('jsonwebtoken');
function generateToken(user) {
return jwt.sign(
{
sub: user.id,
scope: user.permissions,
exp: Math.floor(Date.now() / 1000) + (15 * 60) // 15 minutes
},
process.env.JWT_SECRET,
{ algorithm: 'HS256' }
);
}
JWT 关键安全实践:
- 设置较短的过期时间(15-30 分钟)
- 使用强随机生成的密钥
- 显式验证算法以防止算法混淆攻击
- 为长期会话实现刷新令牌轮换
OAuth 2.0 用于第三方访问
OAuth 2.0 在需要委托授权时表现出色——允许第三方应用程序访问您的 API 而无需共享凭证。对于移动应用和单页应用(SPA),使用带有 PKCE(代码交换证明密钥)扩展的 OAuth 2.0 来防止授权码拦截。
授权:控制用户可以执行的操作
实现基于角色的访问控制(RBAC)
身份验证验证身份;授权确定权限。RBAC 将权限分配给角色而不是单个用户,从而简化访问管理。
const permissions = {
admin: ['read', 'write', 'delete'],
editor: ['read', 'write'],
viewer: ['read']
};
function authorize(requiredPermission) {
return (req, res, next) => {
const userPermissions = permissions[req.user.role];
if (!userPermissions?.includes(requiredPermission)) {
return res.status(403).json({ error: 'Insufficient permissions' });
}
next();
};
}
应用最小权限原则——仅授予每个角色所需的最低访问权限。
Discover how at OpenReplay.com.
速率限制:防止滥用和 DoS 攻击
速率限制可防止暴力破解攻击、DoS 尝试和资源耗尽。根据用户角色或订阅级别实现分层限制。
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 60 * 1000, // 1 minute
max: 100, // requests per window
standardHeaders: true, // Return rate limit info in headers
handler: (req, res) => {
res.status(429).json({
error: 'Too many requests',
retryAfter: req.rateLimit.resetTime
});
}
});
对于分布式系统,使用 Redis 在实例之间共享速率限制计数器。
输入验证:阻止注入攻击
永远不要信任客户端输入。针对严格的模式验证所有传入数据,以防止 SQL 注入、XSS 和命令注入攻击。
const Ajv = require('ajv');
const ajv = new Ajv();
const userSchema = {
type: 'object',
properties: {
email: { type: 'string', format: 'email' },
age: { type: 'integer', minimum: 18, maximum: 120 }
},
required: ['email'],
additionalProperties: false // Prevent mass assignment
};
const validate = ajv.compile(userSchema);
if (!validate(req.body)) {
return res.status(400).json({ errors: validate.errors });
}
加密:保护传输中的数据
始终使用 HTTPS/TLS
对所有 API 端点强制执行 HTTPS——没有例外。尽可能使用 TLS 1.3,并实现 HTTP 严格传输安全(HSTS)头以防止降级攻击。
app.use((req, res, next) => {
res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
next();
});
API 网关安全:集中式保护
像 Kong、AWS API Gateway 或 Tyk 这样的 API 网关为安全策略提供单一控制点。网关处理:
- 身份验证和授权
- 速率限制和流量控制
- 请求/响应转换
- 日志记录和监控
- DDoS 防护
这种集中式方法简化了安全管理,并确保在所有端点上一致地执行策略。
需要避免的常见安全陷阱
永远不要在前端代码中存储密钥。 客户端 JavaScript 中的 API 密钥、令牌和凭证对任何检查代码的人都是可见的。
不要仅依赖 CORS 来保证安全。 CORS 可防止浏览器发出未授权的请求,但无法防止使用 Postman 或 curl 等工具直接调用 API。
避免直接暴露内部服务。 始终通过执行安全策略的 API 网关或反向代理路由外部流量。
不要使用没有轮换的长期令牌。 实现令牌刷新机制,并在注销或可疑活动时使令牌失效。
构建分层 API 安全
没有单一的安全措施能提供完整的保护。有效的 API 安全需要多层协同工作:
- 身份验证验证身份
- 授权控制访问
- 速率限制防止滥用
- 输入验证阻止恶意数据
- 加密保护传输中的数据
- API 网关集中安全控制
每一层都弥补了其他层的潜在弱点。当攻击者绕过一道防线时,下一层会阻止他们。
结论
保护您的 API 免受未授权访问需要的不仅仅是添加身份验证。通过实现 JWT 或 OAuth 2.0 身份验证、RBAC 授权、速率限制、输入验证、HTTPS 加密和 API 网关安全,您可以创建一个强大的防御系统,既能防范外部威胁,也能应对内部风险。
从基础开始——HTTPS、身份验证和速率限制——然后根据您的风险状况逐步添加层级。记住:安全不是一次性实现,而是一个持续的过程,会随着您的 API 和威胁环境的变化而演进。
常见问题
身份验证通过检查密码或令牌等凭证来验证用户身份。授权通过检查权限来确定经过身份验证的用户可以执行的操作。两者都是必不可少的,但在 API 安全中服务于不同的目的。
对于高安全性应用程序,JWT 令牌应在 15 到 30 分钟之间过期。较短的过期时间可以限制令牌被泄露时的损害。使用持续时间更长但可以撤销的刷新令牌来维护用户会话,而无需频繁重新身份验证。
是的,过于严格的速率限制可能会在流量高峰期间阻止合法用户。根据用户角色或订阅级别实现分层限制。监控使用模式以设置适当的阈值,并在达到限制时提供清晰的错误消息和重试信息。
不够,HTTPS 仅加密客户端和服务器之间传输的数据。您仍然需要身份验证、授权、输入验证和速率限制。HTTPS 是必不可少的,但只是全面 API 安全策略中的一层。
Understand every bug
Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.