fix(auth): 微信登录按钮放大+主题色 & /api/auth/aggregate 500 诊断日志\n\nUI 改动(微信登录按钮 + 个人页绑定卡片):\n- OAuthButtons.vue:aggregate 微信按钮 48x48 → 56x56,SVG 图标 22px→28px;默认背景微信绿 #07C160,hover #06ad56,active #059a4c;正常态加绿色阴影,纯 #fff 文字;不再和相邻 Google/GitHub 保持原尺寸不变\n- OAuthBindingCard.vue 个人页卡片:aggregate(aggregate):微信图标框 40x40→48x48(h-10→h-12),图标 22px→26px,背景/边框/文字用微信绿 #07C160;未绑定微信色 立即绑定微信 按钮 字号从 xs→sm,py 1.5→2.5,文案 立即绑定→立即绑定微信\n\n500 排错日志(/api/auth/aggregate):\n- loadAggregateSettings:先取 env fallback 前置,DB select 包 try/catch 不抛;并打印 [AggregateOAuth] enabled/appId/appKey 长度/loginType/endpoint 状态(DB=? 配置 / ENV=? 配置 / dbEnabled回退逻辑\n- auxxStrategy.getAuthorizeUrl 全链路结构化日志:\n 1) 参数打印(enabled/endpoint/safe_ok/redirect_uri/state_len\n 2) 配置缺失时逐条枚举原因(APP_ID 空 / APP_KEY 空 / ENDPOINT 空 / enabled=false)\n 3) endpoint 不合法时单独打印 [AggregateOAuth][auxx][getAuthorizeUrl] endpoint 不合法 + JSON(endpoint)\n 4) 请求 auxx.cn/connect.php?act=login 前打印 GET URL(appkey 替换为 ***,日志绝不输出真实密钥)\n 5) $fetch 成功打印 code/msg/has_url/url_prefix\n 6) $fetch 异常打印 err/status/body (response._data 或 data 前 400 字)\n 7) $fetch 加 15000ms 超时,避免 Runner 到 auxx 不通卡死一直挂 30s\n 以上;30s+ 才被 Nitro 强制 500
This commit is contained in:
@@ -121,9 +121,9 @@
|
|||||||
<div v-if="config.public.oauth.aggregate" :class="itemClass">
|
<div v-if="config.public.oauth.aggregate" :class="itemClass">
|
||||||
<div class="flex items-center gap-4">
|
<div class="flex items-center gap-4">
|
||||||
<div
|
<div
|
||||||
class="w-10 h-10 rounded-xl bg-green-500/10 flex items-center justify-center border border-green-500/20 text-green-500"
|
class="w-12 h-12 rounded-xl bg-[#07C160]/10 flex items-center justify-center border border-[#07C160]/25 text-[#07C160]"
|
||||||
>
|
>
|
||||||
<svg viewBox="0 0 24 24" width="22" height="22" fill="currentColor" aria-hidden="true">
|
<svg viewBox="0 0 24 24" width="26" height="26" fill="currentColor" aria-hidden="true">
|
||||||
<path d="M8.69 3.5C5.06 3.5 2.12 6.03 2.12 9.14c0 1.79 1.04 3.37 2.66 4.41l-.68 2.05 2.56-1.28c.52.11 1.06.17 1.61.17h.51c-.08-.36-.11-.73-.08-1.09H8.69c-2.59 0-4.69-1.93-4.69-4.31s2.1-4.31 4.69-4.31h1.37c.25-.98 1.09-1.7 2.09-1.7.43 0 .83.13 1.17.36C12.61 3.06 10.76 3.5 8.69 3.5zM10.4 5.62c-.93 0-1.69.76-1.69 1.69s.76 1.69 1.69 1.69 1.69-.76 1.69-1.69-.76-1.69-1.69-1.69zm7.19.91c-2.13 0-3.86 1.7-3.86 3.8s1.73 3.8 3.86 3.8c.5 0 1.02-.1 1.47-.27L21.5 15l-.67-1.95c1.21-.88 2-2.24 2-3.72 0-2.1-1.73-3.8-3.84-3.8-.1 0-.2 0-.4.01zm-1.84 2.69c-.66 0-1.2.54-1.2 1.2s.54 1.2 1.2 1.2 1.2-.54 1.2-1.2-.54-1.2-1.2-1.2z"/>
|
<path d="M8.69 3.5C5.06 3.5 2.12 6.03 2.12 9.14c0 1.79 1.04 3.37 2.66 4.41l-.68 2.05 2.56-1.28c.52.11 1.06.17 1.61.17h.51c-.08-.36-.11-.73-.08-1.09H8.69c-2.59 0-4.69-1.93-4.69-4.31s2.1-4.31 4.69-4.31h1.37c.25-.98 1.09-1.7 2.09-1.7.43 0 .83.13 1.17.36C12.61 3.06 10.76 3.5 8.69 3.5zM10.4 5.62c-.93 0-1.69.76-1.69 1.69s.76 1.69 1.69 1.69 1.69-.76 1.69-1.69-.76-1.69-1.69-1.69zm7.19.91c-2.13 0-3.86 1.7-3.86 3.8s1.73 3.8 3.86 3.8c.5 0 1.02-.1 1.47-.27L21.5 15l-.67-1.95c1.21-.88 2-2.24 2-3.72 0-2.1-1.73-3.8-3.84-3.8-.1 0-.2 0-.4.01zm-1.84 2.69c-.66 0-1.2.54-1.2 1.2s.54 1.2 1.2 1.2 1.2-.54 1.2-1.2-.54-1.2-1.2-1.2z"/>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
@@ -131,7 +131,7 @@
|
|||||||
<span class="text-sm font-bold text-zinc-200">{{
|
<span class="text-sm font-bold text-zinc-200">{{
|
||||||
getProviderDisplayName('aggregate')
|
getProviderDisplayName('aggregate')
|
||||||
}}</span>
|
}}</span>
|
||||||
<span v-if="aggregateIdentity" class="text-[11px] text-blue-500 font-medium mt-0.5">{{
|
<span v-if="aggregateIdentity" class="text-[11px] text-[#07C160] font-semibold mt-0.5">{{
|
||||||
aggregateIdentity.providerUsername
|
aggregateIdentity.providerUsername
|
||||||
}}</span>
|
}}</span>
|
||||||
<span v-else class="text-[11px] text-zinc-500 mt-0.5">未绑定</span>
|
<span v-else class="text-[11px] text-zinc-500 mt-0.5">未绑定</span>
|
||||||
@@ -140,7 +140,7 @@
|
|||||||
|
|
||||||
<button
|
<button
|
||||||
v-if="aggregateIdentity"
|
v-if="aggregateIdentity"
|
||||||
class="px-4 py-1.5 bg-rose-500/10 border border-rose-500/20 hover:bg-rose-500/20 text-rose-500 text-xs font-black rounded-xl transition-all disabled:opacity-50"
|
class="px-4 py-2 bg-rose-500/10 border border-rose-500/20 hover:bg-rose-500/20 text-rose-500 text-sm font-semibold rounded-xl transition-all disabled:opacity-50"
|
||||||
:disabled="actionLoading"
|
:disabled="actionLoading"
|
||||||
@click="confirmUnbind('aggregate')"
|
@click="confirmUnbind('aggregate')"
|
||||||
>
|
>
|
||||||
@@ -148,11 +148,11 @@
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-else
|
v-else
|
||||||
class="px-4 py-1.5 bg-emerald-600 hover:bg-emerald-500 text-white text-xs font-black rounded-xl shadow-lg shadow-emerald-900/20 transition-all active:scale-95 disabled:opacity-50"
|
class="px-5 py-2.5 bg-[#07C160] hover:bg-[#06ad56] active:bg-[#059a4c] text-white text-sm font-bold rounded-xl shadow-lg shadow-[#07C160]/30 transition-all active:scale-95 disabled:opacity-50"
|
||||||
:disabled="actionLoading"
|
:disabled="actionLoading"
|
||||||
@click="handleBind('aggregate')"
|
@click="handleBind('aggregate')"
|
||||||
>
|
>
|
||||||
{{ actionLoading ? '跳转中...' : '立即绑定' }}
|
{{ actionLoading ? '跳转中...' : '立即绑定微信' }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
title="使用微信登录"
|
title="使用微信登录"
|
||||||
@click="loginWith('aggregate')"
|
@click="loginWith('aggregate')"
|
||||||
>
|
>
|
||||||
<svg viewBox="0 0 24 24" width="22" height="22" fill="currentColor" aria-hidden="true">
|
<svg viewBox="0 0 24 24" width="28" height="28" fill="currentColor" aria-hidden="true">
|
||||||
<path d="M8.69 3.5C5.06 3.5 2.12 6.03 2.12 9.14c0 1.79 1.04 3.37 2.66 4.41l-.68 2.05 2.56-1.28c.52.11 1.06.17 1.61.17h.51c-.08-.36-.11-.73-.08-1.09H8.69c-2.59 0-4.69-1.93-4.69-4.31s2.1-4.31 4.69-4.31h1.37c.25-.98 1.09-1.7 2.09-1.7.43 0 .83.13 1.17.36C12.61 3.06 10.76 3.5 8.69 3.5zM10.4 5.62c-.93 0-1.69.76-1.69 1.69s.76 1.69 1.69 1.69 1.69-.76 1.69-1.69-.76-1.69-1.69-1.69zm7.19.91c-2.13 0-3.86 1.7-3.86 3.8s1.73 3.8 3.86 3.8c.5 0 1.02-.1 1.47-.27L21.5 15l-.67-1.95c1.21-.88 2-2.24 2-3.72 0-2.1-1.73-3.8-3.84-3.8-.1 0-.2 0-.4.01zm-1.84 2.69c-.66 0-1.2.54-1.2 1.2s.54 1.2 1.2 1.2 1.2-.54 1.2-1.2-.54-1.2-1.2-1.2z"/>
|
<path d="M8.69 3.5C5.06 3.5 2.12 6.03 2.12 9.14c0 1.79 1.04 3.37 2.66 4.41l-.68 2.05 2.56-1.28c.52.11 1.06.17 1.61.17h.51c-.08-.36-.11-.73-.08-1.09H8.69c-2.59 0-4.69-1.93-4.69-4.31s2.1-4.31 4.69-4.31h1.37c.25-.98 1.09-1.7 2.09-1.7.43 0 .83.13 1.17.36C12.61 3.06 10.76 3.5 8.69 3.5zM10.4 5.62c-.93 0-1.69.76-1.69 1.69s.76 1.69 1.69 1.69 1.69-.76 1.69-1.69-.76-1.69-1.69-1.69zm7.19.91c-2.13 0-3.86 1.7-3.86 3.8s1.73 3.8 3.86 3.8c.5 0 1.02-.1 1.47-.27L21.5 15l-.67-1.95c1.21-.88 2-2.24 2-3.72 0-2.1-1.73-3.8-3.84-3.8-.1 0-.2 0-.4.01zm-1.84 2.69c-.66 0-1.2.54-1.2 1.2s.54 1.2 1.2 1.2 1.2-.54 1.2-1.2-.54-1.2-1.2-1.2z"/>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
@@ -152,10 +152,27 @@ const loginWith = (provider: string) => {
|
|||||||
border-color: #dadce0;
|
border-color: #dadce0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.oauth-btn-wechat {
|
||||||
|
width: 56px;
|
||||||
|
height: 56px;
|
||||||
|
background: #07C160;
|
||||||
|
color: #ffffff;
|
||||||
|
border-color: #07C160;
|
||||||
|
box-shadow: 0 4px 12px rgba(7, 193, 96, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
.oauth-btn-wechat:hover {
|
.oauth-btn-wechat:hover {
|
||||||
background: var(--bg-secondary, #07c160);
|
background: #06ad56;
|
||||||
color: var(--text-primary, #ffffff);
|
color: #ffffff;
|
||||||
border-color: var(--border-secondary, #07c160);
|
border-color: #06ad56;
|
||||||
|
box-shadow: 0 6px 18px rgba(7, 193, 96, 0.35);
|
||||||
|
}
|
||||||
|
|
||||||
|
.oauth-btn-wechat:active {
|
||||||
|
background: #059a4c;
|
||||||
|
border-color: #059a4c;
|
||||||
|
transform: translateY(0);
|
||||||
|
box-shadow: 0 2px 8px rgba(7, 193, 96, 0.25);
|
||||||
}
|
}
|
||||||
|
|
||||||
.oauth-empty-hint {
|
.oauth-empty-hint {
|
||||||
|
|||||||
@@ -259,23 +259,34 @@ const strategies: Record<string, OAuthStrategy> = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function loadAggregateSettings() {
|
async function loadAggregateSettings() {
|
||||||
const row = await db
|
|
||||||
.select({
|
|
||||||
aggregateOAuthEnabled: systemSettings.aggregateOAuthEnabled,
|
|
||||||
aggregateOAuthAppId: systemSettings.aggregateOAuthAppId,
|
|
||||||
aggregateOAuthAppKey: systemSettings.aggregateOAuthAppKey,
|
|
||||||
aggregateOAuthLoginType: systemSettings.aggregateOAuthLoginType,
|
|
||||||
aggregateOAuthEndpoint: systemSettings.aggregateOAuthEndpoint
|
|
||||||
})
|
|
||||||
.from(systemSettings)
|
|
||||||
.orderBy(asc(systemSettings.id))
|
|
||||||
.limit(1)
|
|
||||||
const base = row[0] ?? null
|
|
||||||
const envAppId = process.env.AGGREGATE_OAUTH_APP_ID
|
const envAppId = process.env.AGGREGATE_OAUTH_APP_ID
|
||||||
const envAppKey = process.env.AGGREGATE_OAUTH_APP_KEY
|
const envAppKey = process.env.AGGREGATE_OAUTH_APP_KEY
|
||||||
const envLoginType = process.env.AGGREGATE_OAUTH_LOGIN_TYPE
|
const envLoginType = process.env.AGGREGATE_OAUTH_LOGIN_TYPE
|
||||||
const envEndpoint = process.env.AGGREGATE_OAUTH_ENDPOINT
|
const envEndpoint = process.env.AGGREGATE_OAUTH_ENDPOINT
|
||||||
const hasEnvConfig = !!(envAppId && envAppKey && envEndpoint)
|
const hasEnvConfig = !!(envAppId && envAppKey && envEndpoint)
|
||||||
|
|
||||||
|
let base: any = null
|
||||||
|
try {
|
||||||
|
const row = await db
|
||||||
|
.select({
|
||||||
|
aggregateOAuthEnabled: systemSettings.aggregateOAuthEnabled,
|
||||||
|
aggregateOAuthAppId: systemSettings.aggregateOAuthAppId,
|
||||||
|
aggregateOAuthAppKey: systemSettings.aggregateOAuthAppKey,
|
||||||
|
aggregateOAuthLoginType: systemSettings.aggregateOAuthLoginType,
|
||||||
|
aggregateOAuthEndpoint: systemSettings.aggregateOAuthEndpoint
|
||||||
|
})
|
||||||
|
.from(systemSettings)
|
||||||
|
.orderBy(asc(systemSettings.id))
|
||||||
|
.limit(1)
|
||||||
|
base = row[0] ?? null
|
||||||
|
} catch (e: any) {
|
||||||
|
console.warn(
|
||||||
|
'[AggregateOAuth][WARN] loadAggregateSettings 查询 DB 失败,回退只用 process.env 配置。' +
|
||||||
|
` DB 错误:${e?.message || String(e)}。 envAppId=${envAppId ? '已配置(len=' + String(envAppId).length + ')' : '空'} ` +
|
||||||
|
` envEndpoint=${envEndpoint ? '已配置(' + envEndpoint + ')' : '空'}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
const dbEnabled = base?.aggregateOAuthEnabled
|
const dbEnabled = base?.aggregateOAuthEnabled
|
||||||
const dbHasConfig = !!(
|
const dbHasConfig = !!(
|
||||||
base?.aggregateOAuthAppId &&
|
base?.aggregateOAuthAppId &&
|
||||||
@@ -288,7 +299,7 @@ async function loadAggregateSettings() {
|
|||||||
const loginType = ((base?.aggregateOAuthLoginType as string) || envLoginType || '') as string
|
const loginType = ((base?.aggregateOAuthLoginType as string) || envLoginType || '') as string
|
||||||
const endpoint = ((base?.aggregateOAuthEndpoint as string) || envEndpoint || '') as string
|
const endpoint = ((base?.aggregateOAuthEndpoint as string) || envEndpoint || '') as string
|
||||||
|
|
||||||
return {
|
const result: any = {
|
||||||
aggregateOAuthEnabled: enabled && !!(appId && appKey && endpoint),
|
aggregateOAuthEnabled: enabled && !!(appId && appKey && endpoint),
|
||||||
aggregateOAuthAppId: appId,
|
aggregateOAuthAppId: appId,
|
||||||
aggregateOAuthAppKey: appKey,
|
aggregateOAuthAppKey: appKey,
|
||||||
@@ -296,7 +307,19 @@ async function loadAggregateSettings() {
|
|||||||
aggregateOAuthEndpoint: endpoint,
|
aggregateOAuthEndpoint: endpoint,
|
||||||
_dbHasConfig: dbHasConfig,
|
_dbHasConfig: dbHasConfig,
|
||||||
_hasEnvConfig: hasEnvConfig
|
_hasEnvConfig: hasEnvConfig
|
||||||
} as any
|
}
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
'[AggregateOAuth] loadAggregateSettings -> ' +
|
||||||
|
` enabled=${result.aggregateOAuthEnabled}` +
|
||||||
|
` appId=${appId ? 'len=' + String(appId).length : 'EMPTY'}` +
|
||||||
|
` appKey=${appKey ? 'len=' + String(appKey).length : 'EMPTY'}` +
|
||||||
|
` loginType=${loginType || 'EMPTY'}` +
|
||||||
|
` endpoint=${endpoint || 'EMPTY'}` +
|
||||||
|
` (DB=${dbHasConfig ? '有' : '无'}配置, ENV=${hasEnvConfig ? '有' : '无'}配置, dbEnabled=${dbEnabled ?? '未设置->回退ENV'})`
|
||||||
|
)
|
||||||
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizeEndpoint(endpoint: string): string {
|
function normalizeEndpoint(endpoint: string): string {
|
||||||
@@ -321,34 +344,78 @@ function isAuxxEndpoint(endpoint: string): boolean {
|
|||||||
const auxxStrategy: OAuthStrategy = {
|
const auxxStrategy: OAuthStrategy = {
|
||||||
async getAuthorizeUrl(redirectUri: string, state: string) {
|
async getAuthorizeUrl(redirectUri: string, state: string) {
|
||||||
const settings = await loadAggregateSettings()
|
const settings = await loadAggregateSettings()
|
||||||
|
console.log(
|
||||||
|
'[AggregateOAuth][auxx][getAuthorizeUrl] ' +
|
||||||
|
`enabled=${settings?.aggregateOAuthEnabled}` +
|
||||||
|
` endpoint=${settings?.aggregateOAuthEndpoint || 'EMPTY'}` +
|
||||||
|
` endpoint_safe_ok=${isSafeAggregateOAuthUrl(settings?.aggregateOAuthEndpoint || '')}` +
|
||||||
|
` redirect_uri=${redirectUri}` +
|
||||||
|
` state_len=${String(state || '').length}`
|
||||||
|
)
|
||||||
if (!settings?.aggregateOAuthEnabled || !settings.aggregateOAuthAppId || !settings.aggregateOAuthAppKey || !settings.aggregateOAuthEndpoint) {
|
if (!settings?.aggregateOAuthEnabled || !settings.aggregateOAuthAppId || !settings.aggregateOAuthAppKey || !settings.aggregateOAuthEndpoint) {
|
||||||
throw createError({ statusCode: 500, message: '聚合登录未配置' })
|
const hint = []
|
||||||
|
if (!settings?.aggregateOAuthEnabled) hint.push('aggregateOAuthEnabled=false')
|
||||||
|
if (!settings?.aggregateOAuthAppId) hint.push('APP_ID 空')
|
||||||
|
if (!settings?.aggregateOAuthAppKey) hint.push('APP_KEY 空')
|
||||||
|
if (!settings?.aggregateOAuthEndpoint) hint.push('ENDPOINT 空')
|
||||||
|
console.error('[AggregateOAuth][auxx][getAuthorizeUrl] 配置缺失:', hint.join(' | '))
|
||||||
|
throw createError({ statusCode: 500, message: '聚合登录未配置:' + hint.join(' / ') })
|
||||||
}
|
}
|
||||||
if (!isSafeAggregateOAuthUrl(settings.aggregateOAuthEndpoint)) {
|
if (!isSafeAggregateOAuthUrl(settings.aggregateOAuthEndpoint)) {
|
||||||
throw createError({ statusCode: 500, message: '聚合登录端点不安全或格式错误' })
|
console.error(
|
||||||
|
'[AggregateOAuth][auxx][getAuthorizeUrl] endpoint 不合法,' +
|
||||||
|
'isSafeAggregateOAuthUrl 返回 false。endpoint=' +
|
||||||
|
JSON.stringify(settings.aggregateOAuthEndpoint)
|
||||||
|
)
|
||||||
|
throw createError({
|
||||||
|
statusCode: 500,
|
||||||
|
message:
|
||||||
|
'聚合登录端点不安全或格式错误:endpoint 必须是 https://xxx 或内网 http://localhost,当前值=' +
|
||||||
|
settings.aggregateOAuthEndpoint
|
||||||
|
})
|
||||||
}
|
}
|
||||||
const loginTypes = getAggregateOAuthLoginTypesOrDefault(settings.aggregateOAuthLoginType)
|
const loginTypes = getAggregateOAuthLoginTypesOrDefault(settings.aggregateOAuthLoginType)
|
||||||
const loginType = loginTypes[0] || 'qq'
|
const loginType = loginTypes[0] || 'qq'
|
||||||
const endpoint = normalizeEndpoint(settings.aggregateOAuthEndpoint)
|
const endpoint = normalizeEndpoint(settings.aggregateOAuthEndpoint)
|
||||||
const loginQuery = new URLSearchParams({
|
const loginQueryObj: Record<string, string> = {
|
||||||
act: 'login',
|
act: 'login',
|
||||||
appid: settings.aggregateOAuthAppId,
|
appid: settings.aggregateOAuthAppId,
|
||||||
appkey: settings.aggregateOAuthAppKey,
|
appkey: settings.aggregateOAuthAppKey,
|
||||||
type: loginType,
|
type: loginType,
|
||||||
redirect_uri: redirectUri
|
redirect_uri: redirectUri
|
||||||
}).toString()
|
}
|
||||||
|
const loginQuery = new URLSearchParams(loginQueryObj).toString()
|
||||||
|
const debugQueryNoKey = new URLSearchParams({ ...loginQueryObj, appkey: '***' }).toString()
|
||||||
|
console.log(
|
||||||
|
`[AggregateOAuth][auxx][getAuthorizeUrl] 请求 auxx Step1:GET ${endpoint}/connect.php?${debugQueryNoKey}`
|
||||||
|
)
|
||||||
try {
|
try {
|
||||||
const resp: any = await $fetch(`${endpoint}/connect.php?${loginQuery}`, {
|
const resp: any = await $fetch(`${endpoint}/connect.php?${loginQuery}`, {
|
||||||
headers: { Accept: 'application/json' }
|
headers: { Accept: 'application/json' },
|
||||||
|
timeout: 15000
|
||||||
})
|
})
|
||||||
|
console.log(
|
||||||
|
'[AggregateOAuth][auxx][getAuthorizeUrl] auxx Step1 返回:' +
|
||||||
|
JSON.stringify({
|
||||||
|
code: resp?.code,
|
||||||
|
msg: resp?.msg,
|
||||||
|
has_url: !!resp?.url,
|
||||||
|
url_prefix: resp?.url ? String(resp.url).slice(0, 80) + '...' : null
|
||||||
|
})
|
||||||
|
)
|
||||||
if (resp.code !== 0 || !resp.url) {
|
if (resp.code !== 0 || !resp.url) {
|
||||||
throw new Error(resp.msg || '获取登录跳转地址失败')
|
throw new Error(resp.msg || `获取登录跳转地址失败(auxx code=${resp?.code ?? 'N/A'})`)
|
||||||
}
|
}
|
||||||
const sep = resp.url.includes('?') ? '&' : '?'
|
const sep = resp.url.includes('?') ? '&' : '?'
|
||||||
return `${resp.url}${sep}state=${encodeURIComponent(state)}`
|
return `${resp.url}${sep}state=${encodeURIComponent(state)}`
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
console.error('Auxx OAuth authorize URL failed', e)
|
const status = e?.response?.status || e?.status || 'N/A'
|
||||||
throw new Error(e.message || '获取登录跳转地址失败')
|
const body = e?.response?._data ? JSON.stringify(e.response._data).slice(0, 400) : e?.data ? JSON.stringify(e.data).slice(0, 400) : null
|
||||||
|
console.error(
|
||||||
|
'[AggregateOAuth][auxx][getAuthorizeUrl] fetch 异常:' +
|
||||||
|
` err=${e?.message || String(e)} status=${status} body=${body}`
|
||||||
|
)
|
||||||
|
throw new Error(e.message || '获取登录跳转地址失败(auxx 不可达或凭据错误)')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async exchangeToken(code: string, redirectUri: string) {
|
async exchangeToken(code: string, redirectUri: string) {
|
||||||
|
|||||||
Reference in New Issue
Block a user