教程
⚙️

后端开发

Node.js、Python、Go 等服务端开发与 API 设计。

API 认证与授权:JWT、API Key 与 OAuth 怎么选

分清"你是谁"和"你能干啥",掌握 Session/Cookie、JWT、API Key、OAuth2 的适用场景与取舍,避免把凭证设计成安全漏洞。

· 更新于 2026-07-20 阅读量 --

一个公开的 API 谁都能调,但”下单""删数据”这种操作,绝不可能对陌生人开放。这就需要两套机制:认证(Authentication,你是谁)授权(Authorization,你被允许干啥)。日常口语里常混着叫”鉴权”,但设计接口时必须分清。

打个比方:进公司大楼,前台刷工牌确认”你是员工张三”(认证);但张三只能进自己楼层,不能进机房(授权)。工牌证明身份,门禁规则决定权限。这一篇我们把常见的认证授权方案讲透,并告诉你”什么场景用什么”。

先分清:认证 vs 授权

  • 认证(AuthN):确认调用方的身份。“你是谁?“——通过账号密码、手机验证码、第三方登录来证明。
  • 授权(AuthZ):确认这个身份能做什么。“你能不能删这条数据?“——通过角色、权限表来判断。

一个常见误区:以为”登录成功了就啥都能干”。错。登录只是认证,之后每个敏感操作还要做授权检查(比如”当前用户是不是这条数据的拥有者”)。很多越权漏洞,就是忘了做授权这步。

方案一:Session + Cookie(传统 Web)

最早的方案,思路是”服务器记着你是谁”:

  1. 用户登录,服务器校验账号密码,在内存/Redis 里存一个 sessionId → 用户信息 的映射。
  2. sessionId 通过 Set-Cookie 写进浏览器。
  3. 之后每次请求,浏览器自动带上 Cookie,服务器查 session 就知道是谁。

优点:服务端可控,想踢人(删 session)立刻生效。缺点:有状态——session 存在某台服务器内存里,加机器就要做共享存储(Redis),否则用户会”跳登录”。这对 REST 的”无状态”原则是违背的,所以纯 API 服务越来越少用纯 session。

方案二:JWT(无状态令牌,最流行)

JWT(JSON Web Token) 是当下 API 认证的绝对主流。它把”用户身份”直接加密签名进一个 token 字符串里,服务器不需要存任何 session,靠验签就能确认 token 没被篡改。

JWT 长这样(三段用点分隔):

eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxMjN9.xxxxx

三段分别是:头部(算法)、载荷(数据,如 user_id、过期时间)、签名。服务器用密钥验签名,签名对得上就信任里面的 user_id

流程:

1. 用户登录,服务端校验密码,生成 JWT 返回
2. 客户端存 JWT(localStorage 或内存)
3. 之后每次请求在 Header 带:Authorization: Bearer <JWT>
4. 服务端验签 JWT,取出 user_id,知道是谁

优点:无状态,服务器不存会话,天然适合水平扩展的微服务;缺点:token 发出去后无法主动吊销(除非引入黑名单或短过期+刷新机制),且别把敏感信息塞进 JWT(它只是签名,不是加密,payload 可被解码看到)。

JWT 最佳实践:

  • 短期访问令牌 + 长期刷新令牌:access token 5 分钟过期,refresh token 存服务端可吊销,过期后用 refresh 换新的。
  • 密钥绝对不能泄露,且用足够强的算法(HS256 或 RS256)。
  • HTTPS 传输,否则 token 被截获就等于账号被盗。

方案三:API Key(服务对服务)

如果是”程序调程序”(比如你调用天气 API、支付 API),没有”用户登录”概念,常用 API Key:一串随机字符串,调用方放在请求头或参数里。

GET /v1/weather?city=beijing&api_key=xxxxxxxx
# 或放在头里
X-API-Key: xxxxxxxx

优点:简单、适合开放平台限流计费。缺点:key 一旦泄露等于永久凭证,且难以区分”哪个具体用户”。所以 API Key 通常配合速率限制(rate limit)作用域(scope) 使用,且绝不在 URL 里传(会被日志记下来),放 Header 更安全。

方案四:OAuth2(授权第三方)

当你想让”第三方 App”访问”你在某平台的数据”而又不把密码给它,用 OAuth2。典型场景:用微信登录某小游戏、让某记账 App 读取你的邮箱。

核心角色:资源拥有者(你)、客户端(第三方 App)、授权服务器(微信)、资源服务器(存你数据的服务)。流程简化版(授权码模式):

1. 第三方把你重定向到微信的授权页
2. 你点"同意",微信给第三方一个授权码 code
3. 第三方用 code 换 access token(这一步在后端,用户看不到)
4. 第三方拿 token 调用接口读你的数据

OAuth2 解决的是”委托授权”——你把”读头像”的权限有限度地委托给第三方,随时能在微信里收回。它比”直接把账号密码给第三方”安全一万倍。注意:OAuth2 是授权框架,常和 JWT 搭配(token 用 JWT 形式)。

怎么选:一张决策表

场景推荐方案
浏览器网页、要水平扩展的纯 APIJWT(无状态)
传统服务端渲染网站Session + Cookie
开放平台、程序调程序API Key + 限流
第三方登录、委托访问OAuth2
微服务内部调用JWT 或 mTLS

新手常犯的错是”所有场景都上 JWT”,但 JWT 并非银弹:需要”立刻踢人”的系统(如后台封禁),无状态 JWT 反而麻烦,不如 session 或”JWT + 短过期 + 黑名单”。

常见新手坑

  • 把敏感信息塞进 JWT payload:JWT 只是签名不是加密,payload 用 base64 一解就看得见,密码、身份证绝不能放。
  • JWT 不验签名:只 Decode 不 Verify,黑客改了 payload 你也信,等于没认证。务必验签。
  • API Key 放 URL 参数:被代理、网关、浏览器历史全程记录,放 X-API-Key Header。
  • token 永久有效:JWT 不设过期时间,一旦泄露永久可用,必须加 exp
  • HTTPS 没开就传凭证:明文 HTTP 下 token、密码一览无余,凭证接口强制 HTTPS。
  • 只认证不授权:登录后就放行所有操作,导致越权(A 用户删了 B 用户的数据)。

实战:用 JWT 保护一个接口

思路:登录发 token,后续接口校验 token 里的 user_id,再查数据库判断权限:

# 登录
POST /login  {username, password}
-> 200 { token: "eyJ..." }

# 访问受保护接口,带 token
GET /v1/users/123
Headers: Authorization: Bearer eyJ...
-> 服务端验签取出 user_id=123
-> 若 user_id == 123 或该用户是管理员,才返回数据
-> 否则 403 Forbidden

这里既有认证(验 JWT 知道你是 123),又有授权(判断 123 是不是这条数据的 owner,或有没有管理员角色)。两者缺一不可。

新手怎么把认证授权搞明白

认证授权是安全的第一道防线,设计错了就是事故。建议动手搭一个最小系统:用任意后端框架实现”登录发 JWT → 中间件校验 JWT → 受保护接口返回当前用户”。亲手验一遍”没带 token 返回 401、带了过期 token 返回 401、带了别人的 token 但越权返回 403”,比看十篇理论都牢。

另一个心法:永远假设客户端不可信。token 可能被伪造(所以验签)、参数可能被篡改(所以校验)、权限可能被越(所以每次都查授权)。后端不能因为”前端只会在正确情况下调用”就省略检查——攻击者直接拿 curl 打你的接口,根本不经过你的前端。

还有,凭证的传输和存储要贯穿”HTTPS + 不落不安全的地方”这条线。前端别把 token 存进容易被 XSS 读走的 localStorage 当万能解;敏感系统考虑 HttpOnly Cookie。安全和便利永远在权衡,但底线是:凭证绝不明文出现在日志、URL、前端代码里。

小测验:看看你掌握了没

  • 问题一:认证和授权有什么区别?答案:认证回答”你是谁”(身份),授权回答”你能干啥”(权限),两者独立,敏感操作两者都要查。
  • 问题二:JWT 为什么说”无法主动吊销”?怎么缓解?答案:token 自带状态、服务端不存,发出去就认;用短过期 + refresh token + 黑名单缓解。
  • 问题三:OAuth2 解决的是什么问题?答案:第三方委托授权——在不把密码给第三方的前提下,有限度地授权它访问你的数据。

这一篇你该记住的

  • 认证(你是谁)≠ 授权(你能干啥),敏感操作两者都要查,防越权。
  • Session+Cookie 有状态、易控但难扩展;JWT 无状态、易扩展但难主动吊销。
  • JWT 三段:头/载荷/签名;必须验签、设过期、HTTPS、别塞敏感信息。
  • API Key 适合服务间调用,放 Header + 配限流,别放 URL。
  • OAuth2 解决第三方委托授权,常配合 JWT 使用。
  • 选方案看场景:纯 API 用 JWT、开放平台用 API Key、第三方登录用 OAuth2。

下一篇我们讲 统一响应与错误处理:怎么让所有接口返回格式一致、错误清晰可定位,这是专业 API 和玩具 API 的分水岭。