认证与授权
认证(Authentication):你是谁?授权(Authorization):你能干什么?二者常一起考,但要分清。API 错误码见 API 设计与 HTTP 实践。
概念对照
| 术语 | 英文 | 例子 |
|---|---|---|
| 认证 | Authentication | 登录校验身份 |
| 授权 | Authorization | 能否删这条订单 |
| 鉴权 | 常混用 | 口语里常指「认证+授权」 |
请求 → 认证(解析 Token/Session)→ 授权(查角色/权限)→ 业务逻辑
Session vs JWT
| Session(服务端会话) | JWT(自包含 Token) | |
|---|---|---|
| 状态 | 服务端存 session | 服务端可无状态(仅验签) |
| 存储 | Redis / DB | 客户端存(Header/Cookie) |
| 注销 | 删 session 即失效 | 需黑名单或短 TTL + refresh |
| 扩展 | 易集中踢人 | 分布式友好 |
| 体积 | Cookie 里只有 session id | Payload 别塞太大 |
JWT 结构:Header.Payload.Signature(Base64 + HMAC/RSA 签名)。
| 字段 | 说明 |
|---|---|
sub | 用户 id |
exp / iat | 过期 / 签发时间 |
scope / roles | 权限范围(看团队约定) |
Refresh Token:Access 短 TTL + Refresh 长 TTL 换票,减 stolen access 窗口。
OAuth 2.0(直觉)
用于 第三方授权,不是替代密码登录的全部。
| 角色 | 谁 |
|---|---|
| Resource Owner | 用户 |
| Client | 你的应用 |
| Authorization Server | 发 token(IdP) |
| Resource Server | API |
| 模式 | 场景 |
|---|---|
| 授权码(Authorization Code) | Web / 移动端主流;带 PKCE |
| Client Credentials | 服务间 M2M |
| 隐式 / 密码模式 | 不推荐新项目 |
「用 GitHub / 微信登录」= OAuth 授权码 + OpenID Connect(OIDC)拿 id_token 标识用户。
RBAC / ABAC
| 模型 | 说明 |
|---|---|
| RBAC | 用户 → 角色 → 权限(admin/editor) |
| ABAC | 按属性(部门、资源 owner)动态判 |
| ACL | 资源级访问列表 |
大多数业务 RBAC + 资源归属校验(只能改自己的订单)就够。
常见 Header
Authorization: Bearer <access_token>
Cookie + Session:Set-Cookie: sid=...; HttpOnly; Secure; SameSite=Lax
| 安全点 | 说明 |
|---|---|
| HTTPS | 必须 |
| HttpOnly Cookie | 防 XSS 偷 session |
| CSRF | Cookie 会话要 CSRF token 或 SameSite |
| 密码 | bcrypt/argon2,禁明文 |
401 vs 403
| 码 | 含义 |
|---|---|
| 401 | 未提供或无效凭证 |
| 403 | 已认证但无权访问该资源 |
微服务里的身份
| 做法 | 说明 |
|---|---|
| 网关验签 | 内网传 X-User-Id + mTLS |
| Token 透传 | 下游再验 JWT 或 introspection |
| 服务账号 | Client Credentials 调内部 API |
常见误解
- 「JWT 比 Session 更安全」——看密钥管理、TTL、注销策略
- 「OAuth = 登录协议」——它是授权框架;登录常用 OIDC
- 「鉴权放前端就行」——服务端必须再校验
面试速记
- 认证和授权区别? 身份 vs 权限。
- Session 和 JWT 怎么选? 集中会话 vs 无状态;注销与扩缩。
- OAuth 授权码流程? 重定向拿 code → 后端换 token。
- 401 和 403? 未登录 vs 无权限。
- JWT 注销怎么做? 黑名单、短 TTL + refresh、版本号。