fix(auth): 修复生产 hash 路由下社交登录/绑定回跳不跳转
生产构建用 hash 路由(.env.production 里 VITE_ROUTER_HISTORY=hash),但回调地址
是硬拼的、没带 #,社交平台带 code/state 回跳后 vue-router 会解析到 /,落在登录页
而不是 social-login 页面,表现为「扫码后没有任何反应」。开发环境的 .env.development
没有这个变量、走 history 模式,所以只有生产复现。
- login.vue:企业微信扫码的回调地址补 # 前缀
- user-social.vue:社交账号绑定的回调地址补 # 前缀(同一处 bug,此前未暴露)
- util.ts getUrlValue:hash 模式下 ? 后面的参数落在 URL 的 fragment 里,
URL.searchParams 读不到,解析前先摘掉 #;history 模式行为不变
Co-Authored-By: Claude <noreply@anthropic.com>
| | |
| | | urlStr: string = location.href, |
| | | ): string { |
| | | if (!urlStr || !key) return ''; |
| | | const url = new URL(decodeURIComponent(urlStr)); |
| | | // hash 路由(生产构建 VITE_ROUTER_HISTORY=hash)下,? 后面的参数落在 URL 的 fragment 里, |
| | | // URL.searchParams 读不到,参数会被误判成"丢失"。这里先摘掉 # 再解析; |
| | | // history 模式下地址里没有 #,走原逻辑,行为不变。 |
| | | const normalized = urlStr.includes('#') ? urlStr.replace('#', '') : urlStr; |
| | | const url = new URL(decodeURIComponent(normalized)); |
| | | return url.searchParams.get(key) ?? ''; |
| | | } |
| | | |
| | |
| | | wxcpLoading.value = true; |
| | | // 注意:type 需要先 encode 一次,配合 social-login 页面的 getUrlValue() 使用; |
| | | // 否则企业微信回跳后 type 参数会被吞掉,导致无法识别社交类型 |
| | | const redirectUri = `${location.origin}/auth/social-login?${encodeURIComponent( |
| | | // 回调地址必须带 hash 前缀:生产用 hash 路由(VITE_ROUTER_HISTORY=hash), |
| | | // 少了 # 企业微信回跳后 vue-router 会解析到 /,落到登录页而不是 social-login 页面 |
| | | const hashPrefix = |
| | | import.meta.env.VITE_ROUTER_HISTORY === 'hash' ? '/#' : ''; |
| | | const redirectUri = `${location.origin}${hashPrefix}/auth/social-login?${encodeURIComponent( |
| | | `type=${WXCP_SOCIAL_TYPE}`, |
| | | )}`; |
| | | window.location.href = await socialAuthRedirect( |
| | |
| | | try { |
| | | // 计算 redirectUri |
| | | // tricky: type 需要先 encode 一次,否则钉钉回调会丢失。配合 getUrlValue() 使用 |
| | | const redirectUri = `${location.origin}/profile?${encodeURIComponent(`type=${type}`)}`; |
| | | // hash 路由(生产构建)下必须带 # 前缀,否则回跳后 vue-router 解析到 /,进不了绑定流程 |
| | | const hashPrefix = import.meta.env.VITE_ROUTER_HISTORY === 'hash' ? '/#' : ''; |
| | | const redirectUri = `${location.origin}${hashPrefix}/profile?${encodeURIComponent(`type=${type}`)}`; |
| | | |
| | | // 进行跳转 |
| | | window.location.href = await socialAuthRedirect(type, redirectUri); |