OAuth 知识总结

什么是 OAuth

OAuth(Open Authorization)是一个授权协议,让第三方应用可以访问用户在某个平台上的数据,而不需要获取用户的账号密码。

解决的问题: 你想让 App A 读取你的微信好友列表,但不想把微信账号密码给 App A。

OAuth 和 OAuth 2.0 的关系

通常 OAuth 就是指 OAuth 2.0,因为 OAuth 1.0 已几乎废弃。

OAuth 1.0 OAuth 2.0
发布时间 2007 2012
签名方式 必须对每个请求签名(复杂) HTTPS 替代签名(简单)
token 有效期 长期有效 短期 + refresh 机制
现状 已废弃 事实标准

常见授权数据

  • 用户基本信息: 头像、昵称、性别、生日、邮箱、手机号
  • 社交关系: 好友列表、粉丝列表、关注列表
  • 内容数据: 朋友圈、微博、帖子、云盘文件
  • 行为数据: 浏览历史、购买记录、位置历史

核心概念

概念 作用
appId 第三方应用的唯一标识
appSecret 第三方应用的密钥,只存后端
code 一次性临时凭证,暴露在浏览器,只能换 token
access_token API 调用凭证,后端到后端通信,长期有效

为什么不直接用 code 作为 access_token:

  • code 暴露在 URL 地址栏、浏览器历史、日志文件中
  • 有效期太短,用户操作慢一点就失效
  • 只能使用一次,无法重复调用
  • access_token 泄露可以随时吊销

类比:

code = 一次性验证码(只能用一次,几分钟过期)
access_token = 游乐场通行证(2小时内随便进出)

微信授权登录流程

用户              你的网站              微信
 │                  │                   │
 │   点击"微信登录"    │                   │
 │─────────────────►│                   │
 │                  │   请求授权码 code    │
 │                  │──────────────────►│
 │                  │   重定向回网站      │
 │                  │   (带 code 参数)   │
 │◄─────────────────│                   │
 │                  │   用 code 换        │
 │                  │   access_token     │
 │                  │──────────────────►│
 │                  │   返回 access_token │
 │                  │◄─────────────────│
 │                  │   用 token 获取    │
 │                  │   用户信息          │
 │                  │──────────────────►│
 │                  │   返回 openid/UnionID│
 │                  │◄─────────────────│
 │                  │   创建/登录账号     │
 │◄─────────────────│                   │

步骤说明:

  1. 引导用户 — 页面点击"微信登录",跳转微信授权页
  2. 用户授权 — 微信授权页让用户确认(扫码或手机确认)
  3. 拿 code — 微信把用户重定向回你的网站,URL 带 ?code=xxx
  4. 换 token — 你的后端用 code + appSecret 换 access_token
  5. 获取用户信息 — 用 access_token 调用微信 API 获取用户数据
  6. 完成登录 — 关联你的用户系统和微信用户,完成登录

OAuth 2.0 常见授权方式

方式 适用场景
Authorization Code Web 应用(最安全)
PKCE 移动端 App
Client Credentials 服务端之间通信

典型应用场景

  • 用微信登录
  • 用 GitHub 登录
  • 用 Google 登录
  • 第三方应用读取微博好友列表

登录方式分类

登录方式大体分为自建账号体系第三方 OAuth 授权两大类:

自建账号体系

方式 说明
账号密码登录 最传统,用户名+密码
短信验证码登录 手机号+验证码
邮箱登录 邮箱+验证码
扫码登录 手机 APP 扫二维码确认

第三方 OAuth 授权

方式 说明
微信授权登录 OAuth
GitHub / Google 登录 OAuth
Apple 登录 OAuth(iOS 强制要求)
微博 / 抖音登录 OAuth

其他登录方式

方式 说明
指纹 / Face ID 生物识别
硬件 KEY(U盾) 银行常用
邮箱链接登录 点击邮件中的链接确认登录(Magic Link)

简单分类:

登录方式
├── 自建账号体系(密码/短信/邮箱)
└── 第三方授权(OAuth)

现状: 主流 App 通常两种都提供:自建账号体系(手机号)+ 第三方 OAuth(微信/Apple/Google)

登录的本质

登录包含三个层面:

层面 说明
认证(Authentication) 证明你是谁(输入密码/微信授权/指纹等)
会话管理(Session) 保持登录状态(生成 session/token,后续请求带上)
授权(Authorization) 决定你能访问什么(普通用户 vs 管理员)

现实类比:

层面 现实例子
认证 出示身份证证明"我是张三"
会话 刷身份证进门,有效期内随便进出
授权 员工卡能开公司门,但普通员工进不了财务室

登录 = 认证 + 建立会话,授权是登录之后的事

微信授权登录完整接入

准备工作

步骤 说明
1. 注册开放平台账号 https://open.weixin.qq.com
2. 申请开发者资质认证 企业/个人认证,300元/年
3. 创建应用(移动端或网站应用) 获取 AppID 和 appSecret
4. 配置授权回调域名 微信会回调到这个域名

核心获取内容

内容 说明
appId 应用唯一标识(公开的)
appSecret 应用密钥(绝对保密,只存后端)

appId 和 appSecret 的区别

appId appSecret
作用 标识应用 应用密钥
能否暴露 不能
用途 调用授权时传 换 token 时用

appId 的作用: 标识"是哪个应用在发起授权请求"。

微信开放平台上你有多个应用:
- App A(资讯类):appId = wxa123
- App B(电商类):appId = wxb456

用户从 App A 授权登录
         ↓
微信收到授权请求,看到 appId = wxa123
         ↓
微信知道这是 App A 在申请授权

OAuth 流程中的使用:

构建授权 URL:
https://open.weixin.qq.com/connect/qrconnect?
  appId=wxa123        ← appId
  &redirect_uri=xxx
  &response_type=code
  &scope=snsapi_login

注意:微信实际使用的是小写 appId,如 wxa123456789abcdef

技术架构

前端:
- 微信 SDK(微信开放平台提供)
- 调用微信授权的代码

后端:
- 存储 appSecret
- 实现 code 换 token 的接口
- 实现获取用户信息的接口

微信开放平台配置:
- 授权回调域名(你的服务器域名)
- 填入 AppID 和 appSecret

授权回调域名

为什么需要配置

配置回调域名是微信的"安全锁",确保微信只把 code 返回给你指定的服务器。

问题场景:

微信说:用户授权成功了,我把 code 返回给他
坏人的服务器说:我也来接收 code
微信一脸懵:这是谁的服务器?

配置后:

你在微信开放平台填写:www.yourapp.com

微信只接受以下回调:

✅ https://www.yourapp.com/callback?code=xxx
✅ https://yourapp.com/callback?code=xxx
❌ https://evil.com/callback?code=xxx
❌ https://yourapp.evil.com/callback?code=xxx

微信怎么验证

方式 1:校验 HTTP Referrer(简单,常用)

用户授权后,浏览器跳转回你的域名
微信检查请求头里的 Referrer
Referrer 必须是你的备案域名,否则拒绝

方式 2:校验 state 参数(防 CSRF)

你生成一个随机字符串 state
传给微信授权页
微信回调时原样返回 state
你验证 state 是否一致,确保是你发起的请求

回调域名配置 = 告诉微信"我只信任这个域名,其他地方来的一律拒绝"

App 纯微信登录

可行性

完全可行。很多 App(尤其是小程序、移动端 App)都是纯 OAuth 登录。

两种做法

做法 说明
纯 OAuth 登录 只有微信登录,没有账号密码体系
OAuth + 账号体系 两种登录方式都有,用户选其一

纯 OAuth 登录的优缺点

✅ 优点                    ❌ 缺点
─────────────────────    ─────────────────────
用户体验好(一键登录)       用户必须已有微信
开发成本低                  没有微信就登不了
不用担心密码泄露            用户换微信/微信封号 = 账号丢了
不需要管理密码相关功能       无法通过邮箱/手机号找回账号

注意事项

  1. 一个用户用两个微信登录 = 两个账号(因为 openid 不同)
  2. 微信被封 = 账号丢了(无法自救)
  3. 国内部分应用需要兼容(有些用户没有微信)

如何标识唯一用户

通过微信返回的 openid 来标识唯一用户。

openid 是什么:

属性 说明
唯一性 同一个微信用户,对同一个应用,openid 是固定的
范围 不同应用获取同一个用户的 openid 是不同的
格式 类似 oABCD12345xyz 的字符串

工作流程:

微信用户"张三"授权登录你的 App
         ↓
微信返回 openid 给你的后端:`oABCD12345xyz`
         ↓
你的后端用 openid 查数据库:
  - 有记录 → 这是老用户,返回登录成功
  - 没记录 → 这是新用户,创建账号,返回注册成功
         ↓
openid 存在你的用户表里,作为用户的唯一标识

用户表设计示例:

users 表
┌────┬─────────────┬──────────────┬──────────┐
│ id │  nickname   │   openid     │ avatar   │
├────┼─────────────┼──────────────┼──────────┤
│ 1  │ 张三        │ oABCD123...  │ xxx.jpg  │
│ 2  │ 李四        │ oEFGH456...  │ yyy.jpg  │
└────┴─────────────┴──────────────┴──────────┘

多次登录流程:

  • 同一微信用户再次登录 → openid 不变 → 查到同一记录 → 老用户登录
  • 不需要注册新账号

openid = 微信给这个用户在"你的应用"里的唯一身份证,你在数据库里存这个 openid 就行了。

微信小程序登录

微信小程序有自己单独的登录体系,但原理和 OAuth 类似。

小程序 vs 开放平台(网页授权)的区别

小程序登录 开放平台(网页/移动端)
平台 微信小程序 第三方网页/移动 App
登录入口 微信小程序内 微信授权页(扫码等)
获取 code 方式 wx.login() 跳转微信授权页
openid ✅ 相同 ✅ 相同
UnionID 需要用户已关注公众号或绑定手机号 认证后可直接获取

小程序登录流程

用户打开小程序
         ↓
小程序调用 wx.login()
         ↓
微信返回 code(临时凭证)
         ↓
小程序把 code 传到你的后端
         ↓
你的后端用 code + appId + appSecret 换 openid/session_key
         ↓
后端创建用户 session,完成登录

关键点

  • 不需要配置回调域名,因为是微信内部跳转
  • session_key 可以解密小程序内的加密数据(如手机号)
  • openid 逻辑一致:同一个微信号对同一个 appId 是一样的
  • UnionID 在小程序中需要用户已关注公众号或绑定手机号才能获取

一句话总结

小程序是独立的一套,但核心还是拿 code 换 openid,逻辑与开放平台授权相同。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐