feat(auth): 重构认证流程并补充前端登录态保护
- 拆分后端认证处理与会话创建逻辑,支持登录、注册、退出、个人资料和改密接口 - 增加二次验证挑战、Turnstile 人机校验与旧版邮箱迁移清理 - 新增前端认证守卫、管理员访问控制、退出 Hook 与验证工具 - 统一抽离接口类型,优化登录页、注册页和个人资料页的认证交互
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
import * as React from "react"
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
turnstile?: {
|
||||
render: (container: HTMLElement, options: { sitekey: string; callback: (token: string) => void; "expired-callback": () => void; "error-callback": () => void }) => string
|
||||
remove: (widgetId: string) => void
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function TurnstileBox({ siteKey, onToken }: { siteKey: string; onToken: (token: string) => void }) {
|
||||
const ref = React.useRef<HTMLDivElement | null>(null)
|
||||
React.useEffect(() => {
|
||||
if (!siteKey || !ref.current) return
|
||||
let cancelled = false
|
||||
let widgetId = ""
|
||||
function render() {
|
||||
if (cancelled || !ref.current || !window.turnstile) return
|
||||
ref.current.innerHTML = ""
|
||||
widgetId = window.turnstile.render(ref.current, {
|
||||
sitekey: siteKey,
|
||||
callback: onToken,
|
||||
"expired-callback": () => onToken(""),
|
||||
"error-callback": () => onToken(""),
|
||||
})
|
||||
}
|
||||
if (window.turnstile) {
|
||||
render()
|
||||
} else {
|
||||
const existing = document.querySelector('script[src="https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit"]')
|
||||
if (existing) {
|
||||
existing.addEventListener("load", render, { once: true })
|
||||
} else {
|
||||
const script = document.createElement("script")
|
||||
script.src = "https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit"
|
||||
script.async = true
|
||||
script.defer = true
|
||||
script.addEventListener("load", render, { once: true })
|
||||
document.head.appendChild(script)
|
||||
}
|
||||
}
|
||||
return () => {
|
||||
cancelled = true
|
||||
onToken("")
|
||||
if (widgetId && window.turnstile) window.turnstile.remove(widgetId)
|
||||
}
|
||||
}, [siteKey, onToken])
|
||||
return <div className="flex justify-center rounded-md border p-2"><div ref={ref} /></div>
|
||||
}
|
||||
Reference in New Issue
Block a user