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 知识体系总览
下面这张图把本章的核心逻辑串起来了。你一看就明白:
4.7 实战建议
最后,给你几个我在项目中总结的实战建议:
- 永远不要信任客户端:所有认证和授权逻辑必须在服务端完成。前端只是展示层
- 最小权限原则:给每个用户或服务分配刚好够用的权限,不要给太多
- 日志审计:记录所有认证和授权相关的操作,方便事后追溯
- 定期轮换密钥:不管是还是JWT的签名密钥,都要定期更换
- 使用成熟的库:别自己写加密和签名逻辑,用业界验证过的库,比如jjwt、pyjwt
我的习惯:每次新项目启动,我都会先搭好认证和授权的基础设施,哪怕初期用不上。因为后期再加,成本至少翻三倍。你想想看,改一个中间件和改所有接口,哪个更痛苦?
好了,API安全的四个基石就讲到这里。记住:HTTPS是底线,认证和授权是核心,JWT是工具。把这套组合拳打好了,你的API至少能挡住80%的常见攻击。