微信oauth回调地址必须带协议且与公众号后台完全一致,本地开发需用ngrok暴露https地址;网页授权与扫码登录流程不可混用;code一次性有效,token请求须校验状态码并处理错误;openid不宜直接作用户主键,推荐用数据库id作session标识。

微信OAuth回调地址必须带协议且与公众号后台完全一致
微信校验回调域名时严格比对协议、域名、端口和路径,http://localhost:5000/callback 和 https://yourdomain.com/callback 视为两个不同地址。本地开发务必用 ngrok 或 localtunnel 暴露 HTTPS 地址,否则微信拒绝跳转。
常见错误现象:redirect_uri 参数错误 或 invalid redirect_uri;后台配置的「授权回调域名」只填域名(如 example.com),不带 http:// 或路径,但实际请求中的 redirect_uri 必须是完整 URL(含 https://)。
- 公众号后台 → 「开发」→ 「接口权限」→ 「网页授权获取用户基本信息」→ 配置「授权回调域名」为
example.com - 代码中拼接授权 URL 时,
redirect_uri必须是https://example.com/auth/wechat/callback(不能少https,不能多斜杠) - Flask 本地调试建议用
ngrok http 5000,拿到https://xxx.ngrok.io后,在后台配xxx.ngrok.io
Flask路由需区分扫码登录与网页授权两种微信OAuth流程
微信提供两种 OAuth 入口:一种是公众号内点击菜单触发的「网页授权」(静默/手动授权),另一种是独立页面放二维码供用户扫码登录(需调用 getQrConnectUrl)。二者 scope、返回字段、token 获取方式都不同,不能混用。
网页授权走的是 https://open.weixin.qq.com/connect/oauth2/authorize,scope 为 snsapi_base(静默)或 snsapi_userinfo(需用户确认);扫码登录则走微信开放平台的 https://open.weixin.qq.com/connect/qrconnect,scope 固定为 snsapi_login,且需提前在开放平台绑定公众号或移动应用。
- 若只做公众号内 H5 登录,用
snsapi_userinfo+ 网页授权流程即可 - 若要做独立网站扫码登录,必须注册微信开放平台账号,创建网站应用,获取
appid和appsecret,再调用扫码 URL 接口 - Flask 中建议分两个路由:
/auth/wechat/login(跳转授权)和/auth/wechat/callback(接收 code)
requests.get 请求微信 token 接口时必须处理 302 和 JSON 解析异常
微信在获取 access_token 时,若 code 无效或过期,不会返回 JSON 错误体,而是直接返回 HTTP 302 跳转到错误页(导致 requests.get().json() 报 JSONDecodeError)。必须先检查 response.status_code == 200,再解析 JSON。
支持AI生成符合公众号规范的图文,推送至草稿箱;兼容其他技能生成的图文/图片。通过向导扫码授权,支持多账号;无需暴露Secret密钥或配置IP白名单。
另外,微信返回的 token 响应体是标准 JSON,但字段名是中文拼音缩写(如 access_token、expires_in、refresh_token、openid、scope),注意不要写成 access_token 拼错或当成驼峰命名。
- 正确请求示例:
resp = requests.get( "https://api.weixin.qq.com/sns/oauth2/access_token", params={ "appid": "your_appid", "secret": "your_appsecret", "code": request.args.get("code"), "grant_type": "authorization_code" } ) if resp.status_code != 200: return "微信token接口异常", 500 data = resp.json() if "errcode" in data: # 微信自定义错误字段 return f"微信错误:{data['errmsg']}", 400 openid = data["openid"] - code 一次性有效,5分钟过期,且只能用一次;重复使用会返回
{"errcode":40029,"errmsg":"invalid code"} - 别忽略
scope字段——snsapi_base返回的 token 只能查 openid,无法调/sns/userinfo;要用户信息必须用snsapi_userinfo授权
用 Flask-Login 管理用户会话时,微信 openid 不宜直接当 user_id 存数据库
微信 openid 是公众号维度唯一,同一用户关注不同公众号会得到不同 openid;而 unionid 才是微信全平台唯一标识,但只有在用户关注了公众号且该公众号已绑定开放平台时才能拿到。直接拿 openid 当用户主键会导致多公众号场景下账号分裂。
更稳妥的做法是:首次登录时用 openid 查库,无记录则新建;后续登录复用该记录。如果业务需要打通多个公众号或小程序,应在用户授权时尝试获取 unionid(需满足绑定开放平台条件),并存入用户表的 unionid 字段作关联依据。
- 数据库用户表至少保留字段:
openid(索引)、unionid(可空)、nickname、avatar、created_at - Flask-Login 的
UserMixin实现中,get_id()返回数据库用户主键(如id),不是openid - 不要把
access_token或refresh_token存 session——它们有有效期且不应暴露给前端;session 只存user_id即可
微信 OAuth 最容易被忽略的是:公众号网页授权拿到的 access_token 和开放平台的 access_token 完全不通用,前者只能调 /sns/userinfo,后者才能调用户资料、消息群发等高级接口;别指望一个 token 走到底。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










