微信公众号开发H5,OAuth2授权登录,定位服务踩坑 微信 H5 网页授权登录 JS-SDK 定位完整落地指南摘要本文详细记录了基于 Vue3 uni-app 的微信网页 OAuth 授权登录全流程实现以及微信 JS-SDK 定位服务的接入方案。涵盖前端授权跳转、回调页 code 处理、注册状态判断与路由分流、History 模式下的服务端 fallback 配置同时梳理了 JS-SDK 签名校验、wx.config 初始化、getLocation 定位等核心实现并总结了开发过程中常见的坑点与排查思路。技术栈Vue3 TypeScript uni-app Vite适用场景微信公众号 H5 项目、服务号网页授权登录、微信内定位服务一、OAuth 授权登录流程1.1 整体流程下面是完整的 OAuth 授权登录流程否是是第 1 次授权是否否第 2 次授权是否用户点击授权登录是否微信内置浏览器?提示请在微信中打开redirectToWxAuth(state)跳转微信授权页snsapi_base 静默授权微信回调携带 code state重定向到 /pages/auth/callbackstate 是否为 check?调用 userRegistered 判断注册状态是否已注册?跳转 /pages/login/quickLogin快捷登录跳转 /pages/login/index手机号注册页写入 wx_oauth_code 到 storagestate 是否为 login:quickLogin?跳转 /pages/login/quickLogin快捷登录跳转 /pages/login/index手机号注册页登录成功1.2 前置条件在开始编码前必须确认以下配置项配置项位置说明网页授权域名微信公众平台 → 账号设置 → 功能设置填写项目域名不含http://JS 接口安全域名微信公众平台 → 账号设置 → 功能设置JS-SDK 定位需要IP 白名单微信公众平台 → 设置与开发 → 安全中心填写服务器 IP测试正式AppID / AppSecret微信公众平台 → 设置与开发 → 基本配置前后端必须一致注意授权必须要在微信内置浏览器中打开项目因为要跳转微信内部授权页。同时需确保接口使用 https、公众号/服务号已认证、前端部署在 https、项目的 Appid 和给后端的 AppId 及密钥必须确认一致和正确。1.3 核心代码实现判断微信内置浏览器/** 判断是否在微信内UA 含 MicroMessenger */exportfunctionisInWechat():boolean{return/MicroMessenger/i.test(navigator.userAgent)}跳转微信网页授权/** * 跳转微信网页授权snsapi_base 静默授权 * 授权成功后微信会带 code state 重定向到 /pages/auth/callback。 * 注意这是整页跳转无法 await调用后当前页面上下文即销毁。 * param state 透传参数微信会原样带回用于区分回调用途check / login:quickLogin / login:index */exportfunctionredirectToWxAuth(state){if(!isInWechat())returnconstappidbrand.appidif(!appid)return// redirect_uri 必须是完整 URL 且 urlEncode且不能带 #// 项目 router.mode 为 historybase 为 /h5/回调页地址为 /pages/auth/callbackconstredirectUriencodeURIComponent(${location.origin}/pages/auth/callback)consturlhttps://open.weixin.qq.com/connect/oauth2/authorize?appid${appid}redirect_uri${redirectUri}response_typecodescopesnsapi_basestate${encodeURIComponent(state)}#wechat_redirectconsole.log(redirectToWxAuth url:,url)location.hrefurl}授权回调页/pages/auth/callbackscript setup langts import { onLoad } from dcloudio/uni-app import { userRegistered } from /api/login import { useUserStore } from /store // 微信网页授权回调页接收 OAuth 回调的 code // state 区分回调用途 // check → 第 1 次授权判断注册状态已注册跳快捷登录未注册跳注册页 // login:quickLogin → 第 2 次授权已注册取登录 code跳快捷登录 // login:index → 第 2 次授权未注册取登录 code跳手机号注册页 onLoad((query) { let code query?.code if (!code) { // 兜底从 location.hash 再取一次兼容 hash 模式 const queryStr (location.hash || ).split(?)[1] || code new URLSearchParams(queryStr).get(code) || } if (!code) { // 无 code用户拒绝授权/异常不跳转 return } const state query?.state || // 第 1 次授权判断注册状态 if (state check) { userRegistered({ jsCode: code, appId: useUserStore().userInfo.appid }) .then((isRegistered) { const url isRegistered ? /pages/login/quickLogin : /pages/login/index uni.reLaunch({ url }) }) .catch(() { console.error(查询注册状态失败) }) return } // 第 2 次授权取登录 code写入 storage跳回目标登录页 uni.setStorageSync(wx_oauth_code, code) const url state login:quickLogin ? /pages/login/quickLogin : /pages/login/index uni.reLaunch({ url }) }) /script template view classh-screen w-full flex items-center justify-center view classtext-gray-500 正在登录... /view /view /templatemanifest.json 路由配置{h5:{title:,router:{mode:history,base:/}}}1.4 服务端 Fallback 配置必须由于使用 History 模式微信授权回调时刷新页面会导致 404需要服务端配置 fallback 到index.html。Nginx / 静态托管location / { try_files $uri $uri/ /index.html; }IISweb.config放在项目根目录与 index.html 同级?xml version1.0 encodingUTF-8?configurationsystem.webServerrewriterulesrulenameSPA History FallbackstopProcessingtruematchurl(.*)/conditionslogicalGroupingMatchAlladdinput{REQUEST_FILENAME}matchTypeIsFilenegatetrue/addinput{REQUEST_FILENAME}matchTypeIsDirectorynegatetrue//conditionsactiontypeRewriteurl/index.html//rule/rules/rewrite/system.webServer/configurationApache.htaccessIfModule mod_rewrite.c RewriteEngine On RewriteBase / RewriteRule ^index\.html$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.html [L] /IfModule二、定位服务流程2.1 前置配置在微信公众平台配置JS 接口安全域名。2.2 JS-SDK 签名与初始化签名 URL 说明/** * 签名 URL微信按「不含 # 的当前页面 URL」校验签名 * 后端拿 jsapi_ticket noncestr timestamp url当前页面地址一起做 SHA1 生成 signature。 * 微信在校验时会用页面实际加载的 URL 重新算一遍签名和你传的 signature 比对。 * 所以签名必须绑定 URL后端签名时拿到的 URL 必须和前端实际地址完全一致 * 否则 wx.config 会报 invalid signature。 */functiongetSignUrl():string{returnlocation.href.split(#)[0]}初始化 wx.config// 单次页面内复用签名结果避免重复请求letwxConfigPromise:Promiseboolean|nullnullletwxConfigUrl/** * 初始化微信 JS-SDKwx.config * 拉取后端签名 → wx.config → wx.ready 后返回 true失败返回 false非微信环境恒 false * 同一 URL 复用签名结果URL 变化路由切换自动重新签名。 */exportfunctioninitWxConfig():Promiseboolean{if(!isInWechat()||!window.wx)returnPromise.resolve(false)consturlgetSignUrl()if(wxConfigPromisewxConfigUrlurl)returnwxConfigPromise wxConfigUrlurlconsole.log(initWxConfig url:,wxConfigUrl)wxConfigPromisenewPromiseboolean((resolve){// 调后端接口用于获取签名后端需根据 appId 获取 access_token再拿 access_token 和 url 获取 jsapi_ticket最后签名getWxJsSign(brand.appid,url).then((sign){console.log(initWxConfig sign:,sign)window.wx.config({debug:false,// 开发时可设为 true成功或失败都会弹出弹框appId:sign.appId||brand.appid,timestamp:sign.timestamp,nonceStr:sign.nonceStr,signature:sign.signature,jsApiList:[getLocation,openLocation,chooseWXPay],})window.wx.ready(()resolve(true))window.wx.error(()resolve(false))}).catch(()resolve(false))}).then((ok){// 失败清缓存下次调用重试成功则保留复用if(!ok){wxConfigPromisenullwxConfigUrl}returnok})returnwxConfigPromise}/** 手动重置签名缓存登录态变化等场景强制重新签名 */exportfunctionresetWxConfig(){wxConfigPromisenullwxConfigUrl}获取定位/** * 获取用户定位 * 微信内走 JS-SDK wx.getLocation微信自己的定位 授权弹窗精度高返回 gcj02 * 非微信环境降级浏览器 navigator.geolocationuni.getLocation。 * 失败/取消会 reject调用方自行降级。 */exportfunctiongetLocation():Promise{latitude:number,longitude:number}{if(isInWechat()window.wx){console.log(getLocation → 微信内置浏览器)returninitWxConfig().then((ready){if(!ready){console.warn(getLocation → 微信签名失败降级浏览器定位)returnnativeGetLocation()}returnnewPromise((resolve,reject){window.wx.getLocation({type:gcj02,success:(res:any){console.log(getLocation res:,res)returnresolve({latitude:res.latitude,longitude:res.longitude,})},fail:reject,cancel:reject,})})})}console.log(getLocation → 非微信浏览器)returnnativeGetLocation()}三、常见问题排查问题一授权后未返回 callback现象点击按钮触发授权后跳转到了授权页https://open.weixin.qq.com/connect/oauth2/authorize...但没有返回 callback。原因redirect_uri / appid 参数可能不对。排查确认redirect_uri已encodeURIComponent编码确认回调地址域名已在微信公众平台配置为「网页授权域名」确认 appid 前后端一致且项目已认证确认前端部署在 https问题二invalid signature现象wx.config 报错invalid signature。原因签名 URL 与实际页面地址不匹配。排查后端签名时使用的 URL 必须是location.href.split(#)[0]确认每次路由切换后 URL 变化需要重新签名本文 initWxConfig 已按 URL 缓存自动处理开启debug: true查看详细报错确认「JS 接口安全域名」已配置且域名与当前页面一致问题三History 模式回调 404现象微信授权回调到/pages/auth/callback时刷新页面 404。原因服务端未配置 SPA fallback。解决参考 1.4 节配置对应服务器的 fallback 规则将所有非文件/目录请求重写到index.html。四、调试建议建议在项目的index.html中添加以下代码可以在 H5 项目中显示 vConsole 组件类似微信小程序中的开发调试面板方便在真机上查看日志scriptsrchttps://unpkg.com/vconsole3.15.1/dist/vconsole.min.js/scriptscriptnewVConsole()/script同时wx.config 的debug可临时设为true成功或失败都会弹出弹框便于快速定位 JS-SDK 配置问题。总结本文完整梳理了微信 H5 网页授权登录和 JS-SDK 定位两大核心功能的实现方案。授权登录的关键在于两次授权分流设计首次判断注册状态、二次获取登录 code和History 模式的服务端 fallback 配置JS-SDK 定位的核心在于签名 URL 的一致性和wx.config 的正确初始化。按照文中的步骤逐一核对配置与代码可以大幅降低踩坑概率。如果觉得本文有帮助欢迎点赞、收藏、转发 ✨