修复钉钉端内免登循环
This commit is contained in:
parent
26c5e01881
commit
2f5bccb7ee
@ -1,7 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { signIn, useSession } from 'next-auth/react'
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
@ -99,19 +98,42 @@ function formatDingtalkError(error: unknown) {
|
||||
}
|
||||
}
|
||||
|
||||
function submitDingtalkH5Login(authCode: string, redirectPath: string) {
|
||||
const form = document.createElement('form')
|
||||
form.method = 'POST'
|
||||
form.action = `/api/dingtalk/h5-login?redirect=${encodeURIComponent(redirectPath)}`
|
||||
form.style.display = 'none'
|
||||
|
||||
const codeInput = document.createElement('input')
|
||||
codeInput.type = 'hidden'
|
||||
codeInput.name = 'code'
|
||||
codeInput.value = authCode
|
||||
form.appendChild(codeInput)
|
||||
|
||||
document.body.appendChild(form)
|
||||
form.submit()
|
||||
}
|
||||
|
||||
async function hasActiveSession() {
|
||||
try {
|
||||
const response = await fetch('/api/auth/session', {
|
||||
cache: 'no-store',
|
||||
credentials: 'include',
|
||||
})
|
||||
if (!response.ok) return false
|
||||
const data = await response.json().catch(() => null)
|
||||
return Boolean(data?.user)
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
export default function DingtalkEntryClient({ corpId, redirectPath }: DingtalkEntryClientProps) {
|
||||
const { status } = useSession()
|
||||
const startedRef = useRef(false)
|
||||
const [message, setMessage] = useState('正在通过钉钉确认身份...')
|
||||
|
||||
useEffect(() => {
|
||||
if (status === 'authenticated') {
|
||||
window.location.replace(redirectPath)
|
||||
}
|
||||
}, [redirectPath, status])
|
||||
|
||||
useEffect(() => {
|
||||
if (startedRef.current || status === 'loading' || status === 'authenticated') return
|
||||
if (startedRef.current) return
|
||||
startedRef.current = true
|
||||
|
||||
const run = async () => {
|
||||
@ -126,6 +148,12 @@ export default function DingtalkEntryClient({ corpId, redirectPath }: DingtalkEn
|
||||
}
|
||||
|
||||
try {
|
||||
setMessage('正在检查素材库登录状态...')
|
||||
if (await hasActiveSession()) {
|
||||
window.location.replace(redirectPath)
|
||||
return
|
||||
}
|
||||
|
||||
setMessage('正在加载钉钉免登组件...')
|
||||
await loadDingtalkJsApi()
|
||||
|
||||
@ -133,26 +161,14 @@ export default function DingtalkEntryClient({ corpId, redirectPath }: DingtalkEn
|
||||
const authCode = await requestDingtalkAuthCode(corpId)
|
||||
|
||||
setMessage('正在写入素材库登录状态...')
|
||||
const result = await signIn('credentials', {
|
||||
loginType: 'dingtalk_inapp',
|
||||
authCode,
|
||||
redirect: false,
|
||||
})
|
||||
|
||||
if (result?.error) {
|
||||
setMessage(`钉钉免登失败:${result.error}`)
|
||||
return
|
||||
}
|
||||
|
||||
setMessage('登录成功,正在进入考核调研...')
|
||||
window.location.replace(redirectPath)
|
||||
submitDingtalkH5Login(authCode, redirectPath)
|
||||
} catch (error) {
|
||||
setMessage(`钉钉免登失败:${formatDingtalkError(error)}`)
|
||||
}
|
||||
}
|
||||
|
||||
void run()
|
||||
}, [corpId, redirectPath, status])
|
||||
}, [corpId, redirectPath])
|
||||
|
||||
return (
|
||||
<main className="flex min-h-screen items-center justify-center bg-slate-950 px-6 text-slate-50">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user