@@ -92,14 +92,19 @@ export default {
* 发起 OAuth 授权(静默授权,只获取 openid)
* 发起 OAuth 授权(静默授权,只获取 openid)
*/
*/
async startAuth ( ) {
async startAuth ( ) {
// 防止重复调用
// 防止重复调用(实例级 + storage 级双重保护)
if ( this . navigating ) {
if ( this . navigating ) {
console . log ( '[Auth] 已在跳转中,忽略重复 startAuth' ) ;
console . log ( '[Auth] 已在跳转中,忽略重复 startAuth' ) ;
return ;
return ;
}
}
// handleCallback 正在处理中或已完成,禁止发起新授权
if ( uni . getStorageSync ( '__auth_callback_done' ) ) {
console . log ( '[Auth] 回调处理中/已完成,跳过 startAuth' ) ;
return ;
}
this . navigating = true ;
this . navigating = true ;
// 清除上次使用的 code 标记
// 清除上次使用的 code 标记(仅在发起新授权时清除,不在 handleCallback 流程中)
uni . removeStorageSync ( '__used_auth_code' ) ;
uni . removeStorageSync ( '__used_auth_code' ) ;
const platform = detectPlatform ( ) ;
const platform = detectPlatform ( ) ;
@@ -159,12 +164,14 @@ export default {
* 处理授权回调(用 code 换 openid,再用 openid 登录)
* 处理授权回调(用 code 换 openid,再用 openid 登录)
*/
*/
async handleCallback ( code ) {
async handleCallback ( code ) {
// 防止重复调用(redirectTo 是异步的,页面可能被重新触发 )
// 防止重复调用(实例级 + storage 级双重保护 )
if ( this . navigating ) {
if ( this . navigating ) {
console . log ( '[Auth] 已在跳转中,忽略重复 handleCallback' ) ;
console . log ( '[Auth] 已在跳转中,忽略重复 handleCallback' ) ;
return ;
return ;
}
}
this . navigating = true ;
this . navigating = true ;
// storage 级保护:跨页面实例生效,防止支付宝整页重载后重复执行
uni . setStorageSync ( '__auth_callback_done' , '1' ) ;
const appNo = uni . getStorageSync ( 'app_no' ) || getAppNo ( detectPlatform ( ) ) ;
const appNo = uni . getStorageSync ( 'app_no' ) || getAppNo ( detectPlatform ( ) ) ;
@@ -263,11 +270,15 @@ export default {
* 发起非静默授权获取用户信息(snsapi_userinfo,弹窗确认)
* 发起非静默授权获取用户信息(snsapi_userinfo,弹窗确认)
*/
*/
async startUserInfoAuth ( ) {
async startUserInfoAuth ( ) {
// 防止重复调用
// 防止重复调用(实例级 + storage 级双重保护)
if ( this . navigating ) {
if ( this . navigating ) {
console . log ( '[Auth] 已在跳转中,忽略重复 startUserInfoAuth' ) ;
console . log ( '[Auth] 已在跳转中,忽略重复 startUserInfoAuth' ) ;
return ;
return ;
}
}
if ( uni . getStorageSync ( '__auth_callback_done' ) ) {
console . log ( '[Auth] 回调处理中/已完成,跳过 startUserInfoAuth' ) ;
return ;
}
this . navigating = true ;
this . navigating = true ;
// 清除上次使用的 code 标记
// 清除上次使用的 code 标记
@@ -296,8 +307,8 @@ export default {
window . location . origin . replace ( /^http:/ , 'https:' ) + window . location . pathname
window . location . origin . replace ( /^http:/ , 'https:' ) + window . location . pathname
) ;
) ;
// 用户信息授权:微信用 snsapi_userinfo,支付宝用 auth_user
// 用户信息授权:微信用 snsapi_userinfo,支付宝用 auth_userinfo
const scopes = platform === 'alipay' ? 'auth_user' : 'snsapi_userinfo' ;
const scopes = platform === 'alipay' ? 'auth_userinfo ' : 'snsapi_userinfo' ;
// 构建 state(包含 action 和 device_id,回调时原样回传)
// 构建 state(包含 action 和 device_id,回调时原样回传)
const stateObj = { action : 'userinfo' } ;
const stateObj = { action : 'userinfo' } ;
@@ -331,12 +342,13 @@ export default {
* 处理用户信息授权回调(用 code 调 /api/v1/user/info 获取头像昵称)
* 处理用户信息授权回调(用 code 调 /api/v1/user/info 获取头像昵称)
*/
*/
async handleUserInfoCallback ( code ) {
async handleUserInfoCallback ( code ) {
// 防止重复调用
// 防止重复调用(实例级 + storage 级双重保护)
if ( this . navigating ) {
if ( this . navigating ) {
console . log ( '[Auth] 已在跳转中,忽略重复 handleUserInfoCallback' ) ;
console . log ( '[Auth] 已在跳转中,忽略重复 handleUserInfoCallback' ) ;
return ;
return ;
}
}
this . navigating = true ;
this . navigating = true ;
uni . setStorageSync ( '__auth_callback_done' , '1' ) ;
const appNo = uni . getStorageSync ( 'app_no' ) || getAppNo ( detectPlatform ( ) ) ;
const appNo = uni . getStorageSync ( 'app_no' ) || getAppNo ( detectPlatform ( ) ) ;
@@ -410,6 +422,7 @@ export default {
: '/pages/index/index?action=mine' ;
: '/pages/index/index?action=mine' ;
localStorage . removeItem ( '__auth_device_id' ) ;
localStorage . removeItem ( '__auth_device_id' ) ;
localStorage . removeItem ( '__auth_action' ) ;
localStorage . removeItem ( '__auth_action' ) ;
uni . removeStorageSync ( '__auth_callback_done' ) ;
uni . redirectTo ( { url } ) ;
uni . redirectTo ( { url } ) ;
} ,
} ,
@@ -419,6 +432,7 @@ export default {
? ` /pages/index/index?device_id= ${ deviceId } `
? ` /pages/index/index?device_id= ${ deviceId } `
: '/pages/index/index' ;
: '/pages/index/index' ;
localStorage . removeItem ( '__auth_device_id' ) ;
localStorage . removeItem ( '__auth_device_id' ) ;
uni . removeStorageSync ( '__auth_callback_done' ) ;
uni . redirectTo ( { url } ) ;
uni . redirectTo ( { url } ) ;
} ,
} ,
@@ -434,6 +448,7 @@ export default {
const url = this . deviceId
const url = this . deviceId
? ` /pages/register/register?device_id= ${ this . deviceId } `
? ` /pages/register/register?device_id= ${ this . deviceId } `
: '/pages/register/register' ;
: '/pages/register/register' ;
uni . removeStorageSync ( '__auth_callback_done' ) ;
uni . redirectTo ( { url } ) ;
uni . redirectTo ( { url } ) ;
} ,
} ,