/** * 微信静默授权模块 * 支持企业微信(corpId) 和 公众号(appId) 的 snsapi_base 静默授权 * 无外部依赖,原生 JS * * 用法: * 企业微信:const user = WxSilentAuth.cpAuth('wwXXXXXX') * 公众号: const user = await WxSilentAuth.mpAuth('wxXXXXXX') * 两者都不需要时直接调用,有缓存立即返回,无缓存自动跳转授权 */ const WxSilentAuth = (() => { const BASE_API = 'https://yxl.aanboke.cn/prod-api' // ── 工具 ────────────────────────────────────────────────── function getCookie(name) { const m = document.cookie.match(new RegExp('(?:^|; )' + name + '=([^;]*)')) if (!m) return null try { return JSON.parse(decodeURIComponent(m[1])) } catch { return null } } function clearCookie(name) { const exp = 'path=/;expires=' + new Date(0).toUTCString() document.cookie = name + '=;' + exp document.cookie = name + '=;domain=' + document.domain + ';' + exp } function qs(name) { return new URLSearchParams(location.search).get(name) } // ── 企业微信静默授权 ────────────────────────────────────── // // 返回值: // 有缓存 → 返回用户对象 { openId, userId, externalUserId, ... } // 无缓存 → 跳转企业微信授权(函数不返回,页面重定向) // // requireExternal:为 true 时要求用户必须有 externalUserId(外部联系人) // 若缓存中缺少该字段则清除缓存并重新授权,用于需要外部联系人身份的场景 function cpAuth(corpId, requireExternal = false) { corpId = corpId.toLowerCase() const key = corpId + '_user_v2' const user = getCookie(key) if (user) { if (requireExternal && !user.externalUserId) { clearCookie(key) } else { return user } } const params = new URLSearchParams({ redirectUrl: location.href, scope: 'snsapi_base', corpId, suiteId: qs('suiteId') || '', state: location.host }) location.replace(BASE_API + '/api/demo-wechat-work/v1/oauth/url?' + params) } // ── 公众号静默授权 ──────────────────────────────────────── // // 返回值(Promise): // 有缓存 → resolve 用户对象 { openId, nickname, unionId, ... } // 无缓存 → 跳转公众号授权(Promise 永不 resolve,页面重定向) // // cacheKey:自定义 Cookie key,默认为 appId + '_mp_user' // 若后端存储的 Cookie key 不同,通过此参数对齐 async function mpAuth(appId, cacheKey) { const key = cacheKey || appId + '_mp_user' const user = getCookie(key) if (user) return user const url = BASE_API + '/api/demo-wechat-open/v2/api/open/user/' + appId + '/oauth/base/url?redirectUrl=' + encodeURIComponent(location.href) const res = await fetch(url) const json = await res.json() const authUrl = json?.data?.data || json?.value if (authUrl) { location.replace(authUrl) } else { throw new Error('[WxSilentAuth] 获取公众号授权地址失败: ' + JSON.stringify(json)) } } return { cpAuth, mpAuth } })()