为独立开发者设计“Just Enough” API 安全

发布: (2025年12月29日 GMT+8 10:13)
6 min read
原文: Dev.to

Source: Dev.to

不要追求完美。
分层保护你的 API。

为什么 API 安全对独立开发者来说很难

  • 无限的攻击面: 一旦你开始考虑安全,可能的攻击列表就永无止境。
  • 焦虑循环: “如果发生这种攻击怎么办?” → “那这种情形呢?” → 难以继续前进。
  • 资源有限: 你只能管理有限数量的防御措施,所以需要明确的边界。

定义范围

在实现任何东西之前,我问自己:

  • 我会考虑的 – 必须防御的威胁。
  • 我会有意忽略的 – 对于个人项目而言超出范围的攻击。

这不是正式的威胁模型;它在构建 API 的过程中逐步形成。

需要防护的内容

  • 未经身份验证的请求
  • 无效或格式错误的参数
  • 使用被窃取或重放的 JWT 的请求

需要忽略的内容

  • 客户端代码的绝对保密
  • 对原生应用进行完整逆向工程的防御
  • 仅在 API 层阻止所有可能的攻击

分层安全方法

我将职责分配到三个层级。没有任何单一层级被完全信任。

第 1 层 – 客户端

  • JWT 用于用户身份验证
  • Signature(HMAC)用于应用程序标识

第 2 层 – API(Cloudflare Workers + Hono)

  • 应用程序验证(请求签名)
  • JWT 验证与用户识别
  • 基础请求验证(方法、路径、参数)
  • 轻量级速率限制

第 3 层 – 数据库(Supabase)

  • 行级安全(RLS)以强制每个用户的数据隔离

规则: 即使 API 被绕过,其他用户的数据也绝不能被访问。Supabase 的 RLS 在数据库层面强制执行此规则。

应用层验证

为了验证调用方应用,我使用请求签名(HMAC),但 刻意避免

  • 对请求体进行签名
  • 严格的 nonce 管理
  • 完全的重放防护

相反,我仅对以下内容进行签名:

  • timestamp(时间戳)
  • HTTP method(方法)
  • 请求 path(路径)

这种权衡在实现成本、运维复杂度和实际威胁等级之间取得了平衡。由于密钥存放在客户端(React Native)中,针对单人开发的完整 HMAC 级别严谨性并不现实。

相关文章: Protecting the API Entry Point with Cloudflare Workers

日志记录与可观测性

  • 每个请求都会分配一个唯一的 requestId
  • 日志采用结构化 JSON,便于聚合。
  • 向客户端返回的错误响应保持最小化;内部日志能够清晰地区分身份验证失败和授权失败。
  • 在演示中日志输出到控制台,但将输出切换到生产级日志记录器非常简单。

步骤式设计流程

对我而言效果最好的顺序:

  1. 修正假设 – 确定客户端和用户。
  2. 决定威胁边界 – 必须保护的内容与可以忽略的内容。
  3. 锁定数据库 – 启用 RLS(行级安全)以防止跨用户访问。
  4. 确认用户身份 – 实现 JWT 认证。
  5. 在 API 入口处验证请求 – 基础校验,拒绝异常流量。
  6. 如有需要添加应用层标识 – 签名 / 时间戳。
  7. 限制意外的请求突发 – 速率限制。
  8. 使问题可追踪requestId 与结构化日志。

按照这个顺序,我得到了一个 既不过度设计,又不易被意外破坏 的 API 设计。

演示仓库

完整的演示可在以下位置找到:

相关文章: 我如何设计 Supabase 和行级安全 (RLS)

结论

从第一天起就“正确”地设计安全性极其困难,尤其是当你独自工作时。通过:

  • 设定明确的边界,
  • 分层防御,以及
  • 将可观测性视为一等重要的关注点,

你可以实现“恰到好处”的安全性,而不会在复杂性中溺亡。希望本文能帮助你决定自己的 API 安全应当做到何种程度。

Back to Blog

相关文章

阅读更多 »