修复钉钉免登失败兜底跳转

This commit is contained in:
chenpei 2026-07-06 16:06:25 +08:00
parent 6d6c68f813
commit bc7263a597

View File

@ -4,7 +4,11 @@ import {
getAuthSessionCookieCandidates,
resolveSecureAuthCookieFromRequest,
} from '@/lib/auth-cookie'
import { DINGTALK_DIRECT_LOGIN_SOURCE, buildDingtalkOAuthUrl } from '@/lib/dingtalk-oauth'
import {
DINGTALK_DIRECT_LOGIN_SOURCE,
buildDingtalkOAuthUrl,
getDingtalkOAuthClientId,
} from '@/lib/dingtalk-oauth'
import {
getConfiguredDingtalkCorpId,
normalizeDingtalkCorpId,
@ -83,18 +87,58 @@ function createH5LoginPage({
if (status) status.textContent = text;
}
function showError(message) {
function stringifyError(error) {
if (!error) return '';
if (typeof error === 'string') return error;
if (error.message) return String(error.message);
if (error.errorMessage) return String(error.errorMessage);
if (error.errMsg) return String(error.errMsg);
if (error.errmsg) return String(error.errmsg);
try {
return JSON.stringify(error);
} catch (e) {
return String(error);
}
}
function appendFallbackLink() {
if (!status) return;
status.appendChild(document.createElement('br'));
status.appendChild(document.createElement('br'));
var link = document.createElement('a');
link.href = fallbackOAuthUrl;
link.textContent = '改用网页授权登录';
status.appendChild(link);
}
function showError(message, detail) {
if (status) {
status.textContent = message + '。请返回钉钉重新打开通知,或联系管理员检查钉钉免登配置。';
status.appendChild(document.createElement('br'));
status.appendChild(document.createElement('br'));
var link = document.createElement('a');
link.href = fallbackOAuthUrl;
link.textContent = '改用网页授权登录';
status.appendChild(link);
if (detail) {
status.appendChild(document.createElement('br'));
status.appendChild(document.createTextNode('错误详情:' + String(detail).slice(0, 180)));
}
appendFallbackLink();
}
}
function fallbackToOAuth(message, error) {
var detail = stringifyError(error);
console.log('DingTalk H5 login fallback:', message, detail || error || '');
if (status) {
status.textContent = message + ',正在改用网页授权登录...';
if (detail) {
status.appendChild(document.createElement('br'));
status.appendChild(document.createTextNode('错误详情:' + detail.slice(0, 180)));
}
appendFallbackLink();
}
setTimeout(function () {
window.location.replace(fallbackOAuthUrl);
}, 900);
}
window.__failDingtalkLogin = showError;
function completeProfile(user) {
@ -136,6 +180,70 @@ function createH5LoginPage({
});
}
function resolveAuthCode(result) {
return result && (result.code || result.authCode || result.auth_code);
}
function requestAuthCodeWithFallback(dd, previousError) {
if (dd.getAuthCode) {
setStatus('正在尝试钉钉新版免登接口...');
try {
var promiseResult = dd.getAuthCode({ corpId: corpId });
if (promiseResult && typeof promiseResult.then === 'function') {
promiseResult
.then(function (result) {
var code = resolveAuthCode(result);
if (!code) {
fallbackToOAuth('钉钉新版免登接口未返回授权码', result || previousError);
return;
}
submitCode(code);
})
.catch(function (error) {
fallbackToOAuth('钉钉免登授权失败', error || previousError);
});
return;
}
var directCode = resolveAuthCode(promiseResult);
if (directCode) {
submitCode(directCode);
return;
}
} catch (error) {
fallbackToOAuth('钉钉免登授权失败', error || previousError);
return;
}
}
if (dd.requestAuthCode) {
setStatus('正在尝试钉钉备用免登接口...');
try {
dd.requestAuthCode({
corpId: corpId,
clientId: ${stringifyForInlineScript(getDingtalkOAuthClientId())},
onSuccess: function (result) {
var code = resolveAuthCode(result);
if (!code) {
fallbackToOAuth('钉钉备用免登接口未返回授权码', result || previousError);
return;
}
submitCode(code);
},
onFail: function (error) {
fallbackToOAuth('钉钉免登授权失败', error || previousError);
}
});
return;
} catch (error) {
fallbackToOAuth('钉钉免登授权失败', error || previousError);
return;
}
}
fallbackToOAuth('钉钉免登授权失败', previousError);
}
window.__startDingtalkLogin = function () {
if (started) return;
started = true;
@ -143,19 +251,19 @@ function createH5LoginPage({
var dd = window.dd;
if (!dd || !dd.ready || !dd.runtime || !dd.runtime.permission) {
showError('当前页面未检测到钉钉客户端环境');
fallbackToOAuth('当前页面未检测到钉钉客户端环境');
return;
}
var readyTimer = setTimeout(function () {
showError('钉钉免登初始化超时');
fallbackToOAuth('钉钉免登初始化超时');
}, 15000);
if (dd.error) {
dd.error(function (error) {
console.log('DingTalk JSAPI error:', error);
clearTimeout(readyTimer);
showError('钉钉免登初始化失败');
fallbackToOAuth('钉钉免登初始化失败', error);
});
}
@ -173,7 +281,7 @@ function createH5LoginPage({
},
onFail: function (error) {
console.log('requestAuthCode failed:', error);
showError('钉钉免登授权失败');
requestAuthCodeWithFallback(dd, error);
}
});
});
@ -187,7 +295,7 @@ function createH5LoginPage({
];
var scriptIndex = 0;
var loadTimer = setTimeout(function () {
if (!started) showError('钉钉免登组件加载超时');
if (!started) fallbackToOAuth('钉钉免登组件加载超时');
}, 15000);
function loadDingtalkScript() {
@ -206,7 +314,7 @@ function createH5LoginPage({
}
clearTimeout(loadTimer);
showError('钉钉 JSAPI 加载失败');
fallbackToOAuth('钉钉 JSAPI 加载失败');
};
document.head.appendChild(script);
}