4、API安全基石:HTTPS、认证与授权、与JWT令牌

聊到API安全,我见过太多团队把精力全放在业务逻辑上,结果上线第一天就被爬虫薅秃了。说实话,安全这东西,你花80%的精力做基础防护,就能挡住95%的攻击。剩下的5%,那是安全团队的事。

这一章,我们就把API安全的四个核心构件讲透:HTTPS、认证、授权、令牌。这四个东西搞明白了,你的API至少能扛住常规攻击。

4.1 HTTPS:传输层的最后一道防线

先问个问题:你的API还在用HTTP吗?如果是,那你的数据在网络上就是裸奔的。我曾在某电商公司做过渗透测试,用Wireshark抓包,五分钟就拿到了用户的登录密码和支付信息。嗯,那家公司后来被通报了。

HTTPS的核心价值就两点:

  • 加密传输:数据在客户端和服务端之间是密文,中间人拿不到明文
  • 身份验证:客户端能确认服务端的真实身份,防止DNS劫持

你可能会说:「我们用了HTTPS,但性能下降了怎么办?」

其实现在的TLS 1.3已经把握手时间压缩到1-RTT,加上会话复用,性能损耗几乎可以忽略。我建议所有生产环境的API都强制HTTPS,并且在Nginx或网关层做HTTP到HTTPS的301重定向。

核心原则:任何生产环境的API,如果还在用HTTP,那就是在给攻击者送人头。别犹豫,上HTTPS。

4.2 认证 vs 授权:别搞混了

很多新手分不清认证和授权。我面试时经常问这个问题,能答对的人不到一半。

概念 英文 核心问题 类比
认证 Authentication 你是谁? 出示身份证
授权 Authorization 你能做什么? 门禁卡权限

说白了,认证是确认身份,授权是确认权限。你拿着身份证进了公司大门(认证通过),但你的工牌只能刷开普通办公区,进不了机房(授权限制)。

我在项目中见过一个经典错误:某团队在认证通过后,直接把用户ID传给了后端,后端拿着这个ID去查数据库,然后返回所有数据。结果呢?用户A修改了请求中的用户ID,就能看到用户B的订单。这就是典型的「只认证不授权」的坑。

避坑指南:我曾经接手过一个项目,认证逻辑和授权逻辑混在一起写,导致每次改权限都要动认证代码。后来我花了三天时间重构,把认证和授权拆成两个独立的中间件。记住:认证在前,授权在后,各司其职。

4.3 :简单但别滥用

是最简单的认证方式。说白了就是一个字符串,客户端每次请求都带上它,服务端校验通过就放行。

它的优点是简单、轻量、无状态。但缺点也很明显:

  • 安全性低:一旦泄露,任何人都能冒充你
  • 无过期机制:很多是永久有效的,泄露后很难撤销
  • 无法区分用户:一个Key对应一个应用,无法知道具体是哪个用户在操作

我建议只用在以下场景:

  • 服务端到服务端的内部通信(比如微服务之间的调用)
  • 公开API的限流和统计(比如第三方开发者接入)
  • 临时性的测试环境

如果你要用,记得加上这些保护措施:

  • 使用HTTPS传输,别让Key在网络上裸奔
  • 定期轮换Key,比如每90天换一次
  • 在服务端做IP白名单绑定
  • 不要在前端代码里硬编码

小技巧:我习惯在生成时,用UUID加上一个随机盐值做哈希,这样即使数据库泄露,攻击者也拿不到原始Key。

4.4 JWT令牌:现代API的首选

JWT(JSON Web )是目前最流行的API认证方案。它的核心思想是:服务端生成一个令牌,客户端保存这个令牌,每次请求都带上它。服务端不需要保存会话状态,因为令牌本身包含了用户信息和签名。

一个JWT令牌长这样:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

它由三部分组成,用点号分隔:

部分 内容 说明
Header 算法类型、令牌类型 通常是HS256或RS256
Payload 用户信息、过期时间等 不要放敏感信息,因为它是Base64编码,不是加密
Signature 对前两部分的签名 防止令牌被篡改

JWT最大的优势是无状态。服务端不需要存储会话,令牌本身就能验证用户身份。这在微服务架构下特别有用——每个服务都能独立验证JWT,不需要去中心化的认证服务查会话。

但JWT也有坑,我踩过不少:

  • 令牌无法撤销:一旦签发,在过期前都是有效的。解决方案是维护一个黑名单,或者用短过期时间+刷新令牌
  • Payload是明文:别把密码、信用卡号放进去。Base64不是加密,是编码
  • 签名算法混淆:曾经有攻击者把RS256改成HS256,用公钥当密钥签名,成功伪造了令牌。记得在服务端强制指定算法

最佳实践:我建议JWT的过期时间设为15-30分钟,配合一个长期有效的刷新令牌(Refresh )。这样即使JWT泄露,攻击者也只有很短的时间窗口可用。

4.5 四种方案的对比与选择

说了这么多,到底该用哪种?我整理了一张对比表:

方案 安全性 性能 适用场景 推荐指数
HTTPS 高 中(TLS握手开销) 所有API ★★★★★
低 高 服务间通信、公开API ★★★☆☆
JWT 高 高 用户认证、微服务 ★★★★★
Session 中 低(需存储会话) 传统Web应用 ★★☆☆☆

我个人习惯的组合是:HTTPS + JWT + 短过期时间 + 刷新令牌。这套组合能覆盖90%的API场景。如果是对内服务,可以退而求其次用,但一定要加IP白名单。

4.6 知识体系总览

下面这张图把本章的核心逻辑串起来了。你一看就明白:

API安全基石知识体系 API安全基石知识体系 API安全 HTTPS 认证 授权 令牌 TLS 1.3 / 证书 用户名密码 / OAuth RBAC / ABAC JWT / 最佳实践:HTTPS + JWT + 短过期 + 刷新令牌 + 权限校验 四个核心构件层层递进,缺一不可 HTTPS是基础,认证确认身份,授权控制权限,令牌承载凭证

4.7 实战建议

最后,给你几个我在项目中总结的实战建议:

  1. 永远不要信任客户端:所有认证和授权逻辑必须在服务端完成。前端只是展示层
  2. 最小权限原则:给每个用户或服务分配刚好够用的权限,不要给太多
  3. 日志审计:记录所有认证和授权相关的操作,方便事后追溯
  4. 定期轮换密钥:不管是还是JWT的签名密钥,都要定期更换
  5. 使用成熟的库:别自己写加密和签名逻辑,用业界验证过的库,比如jjwt、pyjwt

我的习惯:每次新项目启动,我都会先搭好认证和授权的基础设施,哪怕初期用不上。因为后期再加,成本至少翻三倍。你想想看,改一个中间件和改所有接口,哪个更痛苦?

好了,API安全的四个基石就讲到这里。记住:HTTPS是底线,认证和授权是核心,JWT是工具。把这套组合拳打好了,你的API至少能挡住80%的常见攻击。