4、API认证与授权机制:API Key、Basic Auth、OAuth 2.0流程详解,Token管理与刷新策略
说到API集成,绕不开的一个话题就是认证与授权。我见过太多项目,功能都写好了,结果卡在认证这一关。说白了,你连门都进不去,还谈什么数据交互?
这一章,咱们就把三种主流的认证方式掰开揉碎了讲清楚。API Key、Basic Auth、OAuth 2.0,我会结合我在CRM项目中的实际踩坑经历,帮你彻底搞明白。
4.1 API Key:最简单的入门方式
API Key,其实就是一串唯一的字符串。你把它放在请求头里,服务器一看就知道你是谁。
怎么用?
通常放在HTTP Header里,像这样:
GET /api/v1/contacts HTTP/1.1
Host: crm.example.com
X-API-Key: abc123def456ghi789
也有的服务要求放在查询参数里:
GET /api/v1/contacts?api_key=abc123def456ghi789
适用场景
- 内部系统之间的简单调用
- 公开API的限流与统计
- 低安全要求的只读接口
缺点也很明显
- Key一旦泄露,别人就能冒充你
- 没有过期机制,除非手动轮换
- 无法区分具体用户,只能识别应用
4.2 Basic Auth:老牌但别乱用
Basic Auth,说白了就是把用户名和密码拼在一起,用Base64编码一下,塞进请求头里。
格式长这样:
Authorization: Basic base64(username:password)
举个例子,用户名是 admin,密码是 secret123,那么:
Authorization: Basic YWRtaW46c2VjcmV0MTIz
什么时候用?
- 快速测试接口时
- 内部网络中的服务间调用
- 一些老系统的兼容需求
什么时候别用?
- 面向公网的API
- 需要精细权限控制的场景
- 移动端或前端应用
我记得有一次,一个第三方服务商坚持用Basic Auth对接我们的CRM。我反复确认他们走的是HTTPS,并且限制了IP范围。即便如此,我还是建议他们尽快升级到OAuth 2.0。你想想看,密码每次请求都带着,风险太大了。
4.3 OAuth 2.0:现代API的标配
OAuth 2.0,现在几乎是所有正经API的标配了。它不是一种认证方式,而是一个授权框架。说白了,就是让用户授权第三方应用访问他的数据,而不需要交出密码。
核心角色
| 角色 | 说明 |
|---|---|
| 资源所有者 | 就是用户本人,拥有数据的人 |
| 客户端 | 想要访问用户数据的应用,比如你的CRM系统 |
| 授权服务器 | 负责验证用户身份,颁发令牌 |
| 资源服务器 | 存放用户数据的API服务 |
最常用的授权模式:授权码模式
这个流程我画过无数遍,咱们一步步来:
- 用户点击「使用微信登录」
- 你的CRM把用户重定向到微信授权页面
- 用户输入账号密码,同意授权
- 微信返回一个授权码(Authorization Code)到你的回调地址
- 你的CRM用这个授权码,加上自己的Client Secret,去换Access Token
- 拿到Token后,就可以调用微信API获取用户信息了
代码示例:用Python请求Token
import requests
# 用授权码换取Access Token
url = "https://oauth.crm.com/token"
data = {
"grant_type": "authorization_code",
"code": "auth_code_here",
"redirect_uri": "https://your-crm.com/callback",
"client_id": "your_client_id",
"client_secret": "your_client_secret"
}
response = requests.post(url, data=data)
token_data = response.json()
access_token = token_data["access_token"]
refresh_token = token_data["refresh_token"]
expires_in = token_data["expires_in"]
4.4 Token管理与刷新策略
拿到Token只是第一步,怎么管好它才是真功夫。我见过不少团队,Token过期了也不知道,导致线上服务突然中断。
Token的生命周期
Access Token通常有效期很短,15分钟到1小时不等。Refresh Token有效期长一些,可能是7天、30天甚至更长。
刷新策略
我一般推荐两种做法:
- 提前刷新:在Token过期前5分钟,主动用Refresh Token去换新的Access Token。
- 失败重试:调用API时如果收到401错误,自动触发刷新流程,然后重试请求。
代码示例:自动刷新逻辑
class CRMClient:
def __init__(self, client_id, client_secret):
self.client_id = client_id
self.client_secret = client_secret
self.access_token = None
self.refresh_token = None
self.expires_at = 0
def _is_token_expired(self):
import time
return time.time() >= self.expires_at
def _refresh_access_token(self):
# 用Refresh Token换新的Access Token
url = "https://oauth.crm.com/token"
data = {
"grant_type": "refresh_token",
"refresh_token": self.refresh_token,
"client_id": self.client_id,
"client_secret": self.client_secret
}
response = requests.post(url, data=data)
token_data = response.json()
self.access_token = token_data["access_token"]
self.refresh_token = token_data.get("refresh_token", self.refresh_token)
self.expires_at = time.time() + token_data["expires_in"]
def call_api(self, endpoint):
if self._is_token_expired():
self._refresh_access_token()
headers = {"Authorization": f"Bearer {self.access_token}"}
response = requests.get(endpoint, headers=headers)
if response.status_code == 401:
# 万一Token还是失效了,再试一次
self._refresh_access_token()
headers["Authorization"] = f"Bearer {self.access_token}"
response = requests.get(endpoint, headers=headers)
return response.json()
安全存储建议
- Token不要硬编码在代码里,用环境变量或密钥管理服务
- 数据库存储Token时,至少要做加密处理
- 定期轮换Client Secret
- 监控Token的使用情况,发现异常立即吊销
4.5 三种方式对比总结
| 特性 | API Key | Basic Auth | OAuth 2.0 |
|---|---|---|---|
| 安全等级 | 低 | 中(需HTTPS) | 高 |
| 实现复杂度 | 简单 | 简单 | 中等 |
| 支持过期 | 否 | 否 | 是 |
| 支持权限细分 | 否 | 否 | 是 |
| 适用场景 | 内部简单调用 | 快速测试/内部 | 生产环境/第三方集成 |
嗯,这一章的内容就到这里。总结一下:API Key适合快速上手,Basic Auth适合内部使用,OAuth 2.0才是生产环境的正确选择。Token管理看似麻烦,但做好了能省去很多线上故障的麻烦。
下一章,咱们聊聊实际对接第三方API时,那些文档里不会写的坑。到时候见。