1. 微信登录流程概述
微信登录作为现代移动应用最常用的第三方登录方式之一,其背后隐藏着一套严谨的OAuth2.0授权流程。我第一次对接微信登录时,被那些code、state、access_token绕得头晕,直到亲手调试了整套流程才恍然大悟。这套机制既要保证用户信息安全,又要兼顾开发者便利性,设计确实精妙。
典型的微信登录包含五个核心环节:前端发起授权→微信返回临时code→服务端用code换token→获取用户基本信息→建立自身业务系统的用户体系。每个环节都有必须注意的安全校验点,稍有不慎就会导致对接失败或安全漏洞。下面我将结合具体代码示例,拆解每个步骤的技术细节。
2. 前期准备工作
2.1 申请开发者资质
在微信开放平台(open.weixin.qq.com)申请账号时,需要准备营业执照等企业资质。个人开发者只能申请测试账号,有300个用户限制。这里有个坑:同一个身份证号不能同时注册个人和企业的开发者账号。
重要提示:主体类型一旦选择不可更改,企业账号需要微信支付商户号才能申请移动应用
2.2 创建移动应用
填写应用基本信息时,"应用签名"需要特别注意。Android平台使用签名文件的MD5值(去掉冒号),获取方法:
keytool -list -v -keystore your_keystore.jksiOS的Bundle ID必须与Xcode中的完全一致,包括大小写。我们团队曾因Bundle ID多了一个空格导致审核被拒三次。
2.3 配置开发信息
在"开发信息"栏目需要配置:
- 授权回调域(如www.yourdomain.com)
- iOS的Universal Links
- Android的签名包名
这里有个隐藏规则:回调域名不能带http://和路径,必须是纯域名。配置生效通常需要10分钟,但遇到缓存问题时可能需要等1小时。
3. 前端授权流程实现
3.1 生成授权链接
标准的OAuth2.0授权链接格式如下:
https://open.weixin.qq.com/connect/oauth2/authorize? appid=APPID& redirect_uri=ENCODED_URL& response_type=code& scope=snsapi_userinfo& state=STATE#wechat_redirect参数说明:
- scope: snsapi_base(静默授权)或snsapi_userinfo(需用户确认)
- state建议用随机字符串防CSRF攻击
- redirect_uri必须urlencode处理
3.2 处理微信回调
当用户在微信客户端确认授权后,会跳转到指定redirect_uri并附加code和state参数。前端需要:
- 校验state是否与发起时一致
- 立即将code发送到自己服务器(不能在前端使用code)
- 处理可能的错误码(如用户取消授权返回errmsg)
典型错误案例:
// 错误!code不能在前端使用 const code = getUrlParam('code'); wx.getUserInfo({ code });4. 服务端核心交互
4.1 用code换取access_token
向微信接口发起HTTPS请求:
GET https://api.weixin.qq.com/sns/oauth2/access_token? appid=APPID& secret=SECRET& code=CODE& grant_type=authorization_code响应示例:
{ "access_token": "ACCESS_TOKEN", "expires_in": 7200, "refresh_token": "REFRESH_TOKEN", "openid": "OPENID", "scope": "SCOPE" }关键注意事项:
- code有效期5分钟且只能使用一次
- 务必校验返回的scope是否与请求一致
- access_token有效期2小时需要缓存
4.2 刷新access_token
当access_token过期时,使用refresh_token刷新:
GET https://api.weixin.qq.com/sns/oauth2/refresh_token? appid=APPID& grant_type=refresh_token& refresh_token=REFRESH_TOKENrefresh_token有效期30天,建议在用户每次活跃时主动刷新。
4.3 获取用户信息
最后调用:
GET https://api.weixin.qq.com/sns/userinfo? access_token=ACCESS_TOKEN& openid=OPENID& lang=zh_CN返回数据包含昵称、头像、地区等信息。注意:
- 需要scope为snsapi_userinfo
- 头像建议转存到自己CDN(微信头像URL会失效)
- 敏感信息需要加密存储
5. 业务系统对接方案
5.1 用户体系设计
建议的数据库表结构:
CREATE TABLE `wx_users` ( `id` bigint PRIMARY KEY, `openid` varchar(64) UNIQUE, `unionid` varchar(64), `nickname` varchar(64), `avatar` varchar(255), `access_token` varchar(256), `refresh_token` varchar(256), `expires_at` datetime );当unionid可用时(同一开放平台下多个应用),应该优先使用unionid作为用户唯一标识。
5.2 会话管理方案
推荐JWT方案的工作流程:
- 微信登录成功后生成业务系统的JWT
- JWT中存储openid/unionid和必要业务信息
- 设置合理过期时间(建议2小时)
- 通过refresh_token机制延长会话
5.3 安全防护措施
必须实现的防护:
- 所有接口的CSRF防护
- 用户信息传输加密
- 接口调用频率限制
- 异地登录检测
- 敏感操作二次验证
6. 常见问题排查
6.1 错误码速查表
| 错误码 | 含义 | 解决方案 |
|---|---|---|
| 40029 | code无效 | 检查code是否重复使用或过期 |
| 40163 | code已使用 | 每个code只能兑换一次 |
| 41008 | 缺少code参数 | 检查授权回调URL |
| 42001 | token过期 | 使用refresh_token刷新 |
| 43002 | 需要用户授权 | 检查scope是否为snsapi_userinfo |
6.2 调试技巧
- 使用微信开发者工具的真机调试功能
- 抓包检查HTTPS请求(需配置Charles证书)
- 服务端日志记录完整请求/响应
- 微信开放平台有调用量统计工具
6.3 性能优化建议
- 实现token的本地缓存(Redis最佳)
- 批量获取用户信息时使用unionid
- 异步更新用户头像等非关键信息
- 建立token自动刷新机制
7. 高级功能扩展
7.1 移动端快速登录
通过微信SDK实现一键登录:
// iOS示例 SendAuthReq *req = [[SendAuthReq alloc] init]; req.scope = @"snsapi_userinfo"; req.state = @"随机字符串"; [WXApi sendReq:req completion:nil];7.2 小程序登录方案
小程序有独立流程:
- 调用wx.login获取code
- 用code换session_key
- 解密getUserInfo返回的加密数据
关键区别是session_key需要用来解密用户信息。
7.3 公众号网页授权
在微信浏览器内访问时:
- 静默授权获取openid(snsapi_base)
- 用户操作时触发完整授权(snsapi_userinfo)
- 注意域名必须与公众号JS安全域名一致
我在实际项目中发现,微信登录最关键的还是理解OAuth2.0的授权码模式本质。所有参数都有明确的安全考量,比如state防CSRF、code防重放攻击。建议开发时先通读微信官方文档的"授权流程说明"章节,再结合本文的实操细节,能少踩很多坑。