OAuth2.0授权登录
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│
│ │◄─────────────────│
│ │ 创建/登录账号 │
│◄─────────────────│ │
步骤说明:
- 引导用户 — 页面点击"微信登录",跳转微信授权页
- 用户授权 — 微信授权页让用户确认(扫码或手机确认)
- 拿 code — 微信把用户重定向回你的网站,URL 带
?code=xxx - 换 token — 你的后端用 code + appSecret 换 access_token
- 获取用户信息 — 用 access_token 调用微信 API 获取用户数据
- 完成登录 — 关联你的用户系统和微信用户,完成登录
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 登录的优缺点
✅ 优点 ❌ 缺点
───────────────────── ─────────────────────
用户体验好(一键登录) 用户必须已有微信
开发成本低 没有微信就登不了
不用担心密码泄露 用户换微信/微信封号 = 账号丢了
不需要管理密码相关功能 无法通过邮箱/手机号找回账号
注意事项
- 一个用户用两个微信登录 = 两个账号(因为 openid 不同)
- 微信被封 = 账号丢了(无法自救)
- 国内部分应用需要兼容(有些用户没有微信)
如何标识唯一用户
通过微信返回的 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,逻辑与开放平台授权相同。
更多推荐


所有评论(0)