fix: 补齐内网登录异常回传
This commit is contained in:
parent
3f56e0280f
commit
192c1f395b
@ -28,7 +28,7 @@ function isSafeHandoffNonce(value: unknown) {
|
||||
|
||||
async function attachInternalSessionHandoff(source: NextResponse, state: unknown) {
|
||||
const data = await source.clone().json().catch(() => null)
|
||||
if (!source.ok || !data?.success || data?.needCompleteProfile || !data?.user?.id) {
|
||||
if (!data) {
|
||||
return source
|
||||
}
|
||||
|
||||
@ -43,6 +43,24 @@ async function attachInternalSessionHandoff(source: NextResponse, state: unknown
|
||||
return source
|
||||
}
|
||||
|
||||
// 首次补资料和授权失败都还没有可交接的内网会话,但弹窗必须能把结果送回原内网页面。
|
||||
// 目标地址只来自服务器保存的受信 handoff,绝不能回退为 postMessage('*')。
|
||||
if (!source.ok || !data?.success || data?.needCompleteProfile || !data?.user?.id) {
|
||||
const response = NextResponse.json(
|
||||
{
|
||||
...data,
|
||||
handoffTargetOrigin: handoff.returnOrigin,
|
||||
handoffNonce: nonce,
|
||||
},
|
||||
{
|
||||
status: source.status,
|
||||
headers: { 'Cache-Control': 'no-store' },
|
||||
},
|
||||
)
|
||||
appendSetCookies(response, getSetCookies(source))
|
||||
return response
|
||||
}
|
||||
|
||||
const ticket = await createDingtalkSessionTicket({
|
||||
userId: String(data.user.id),
|
||||
redirectPath: handoff.redirectPath,
|
||||
@ -84,8 +102,12 @@ async function attachInternalSessionHandoff(source: NextResponse, state: unknown
|
||||
*/
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
let state: unknown = ''
|
||||
|
||||
try {
|
||||
const { code, state } = await request.json()
|
||||
const body = await request.json()
|
||||
const { code } = body
|
||||
state = body?.state
|
||||
|
||||
if (!code) {
|
||||
return NextResponse.json(
|
||||
@ -101,12 +123,13 @@ export async function POST(request: NextRequest) {
|
||||
return attachInternalSessionHandoff(response, state)
|
||||
} catch (error: any) {
|
||||
console.error('钉钉登录失败:', error)
|
||||
return NextResponse.json(
|
||||
const response = NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
message: error.message || '登录失败,请稍后再试',
|
||||
},
|
||||
{ status: 500 },
|
||||
)
|
||||
return attachInternalSessionHandoff(response, state)
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,7 +94,13 @@ function DingtalkCallbackContent() {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok || !data.success) {
|
||||
throw new Error(data.message || '登录失败')
|
||||
const loginError = new Error(data.message || '登录失败') as Error & {
|
||||
handoffTargetOrigin?: string
|
||||
handoffNonce?: string
|
||||
}
|
||||
loginError.handoffTargetOrigin = data?.handoffTargetOrigin
|
||||
loginError.handoffNonce = data?.handoffNonce
|
||||
throw loginError
|
||||
}
|
||||
|
||||
// 检查是否需要完善信息
|
||||
@ -113,7 +119,7 @@ function DingtalkCallbackContent() {
|
||||
userInfo: data.user,
|
||||
nonce,
|
||||
},
|
||||
window.location.origin,
|
||||
data.handoffTargetOrigin || window.location.origin,
|
||||
)
|
||||
window.close()
|
||||
} else if (window.parent !== window) {
|
||||
@ -124,7 +130,7 @@ function DingtalkCallbackContent() {
|
||||
userInfo: data.user,
|
||||
nonce,
|
||||
},
|
||||
window.location.origin,
|
||||
data.handoffTargetOrigin || window.location.origin,
|
||||
)
|
||||
} else {
|
||||
router.push(`/complete-profile?userInfo=${userInfoParam}`)
|
||||
@ -195,16 +201,25 @@ function DingtalkCallbackContent() {
|
||||
setTimeout(() => {
|
||||
if (window.opener) {
|
||||
// 新窗口模式:通知打开窗口的父页面
|
||||
const targetOrigin = error?.handoffTargetOrigin
|
||||
if (!targetOrigin || error?.handoffNonce !== parseDingtalkLoginState(state).nonce) {
|
||||
// 若连受信 handoff 都无法确认,保留错误页给用户看,不能关闭弹窗后让内网页面无提示地卡住。
|
||||
return
|
||||
}
|
||||
window.opener.postMessage(
|
||||
{ type: 'dingtalk_login_error', message: error.message, nonce: parseDingtalkLoginState(state).nonce },
|
||||
window.location.origin,
|
||||
targetOrigin,
|
||||
)
|
||||
window.close()
|
||||
} else if (window.parent !== window) {
|
||||
// iframe模式:通知父窗口(兼容旧代码)
|
||||
const targetOrigin = error?.handoffTargetOrigin
|
||||
if (!targetOrigin || error?.handoffNonce !== parseDingtalkLoginState(state).nonce) {
|
||||
return
|
||||
}
|
||||
window.parent.postMessage(
|
||||
{ type: 'dingtalk_login_error', message: error.message, nonce: parseDingtalkLoginState(state).nonce },
|
||||
window.location.origin,
|
||||
targetOrigin,
|
||||
)
|
||||
} else {
|
||||
router.push('/login')
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user