feat(auth): 将iframe通信从用户名改为令牌验证

This commit is contained in:
JiaJun
2026-04-21 17:00:32 +08:00
parent 195cba9d6e
commit a071d07a7c
9 changed files with 126 additions and 67 deletions

View File

@@ -143,20 +143,25 @@
<div class="layout">
<aside class="panel">
<h1>PlayX Host Test</h1>
<p>Use this page to test iframe embedding and the <code>PLAYX_READY</code> / <code>IFRAME_CONTEXT</code> handshake flow.</p>
<p>Use this page to test iframe embedding and the <code>IFRAME_READY</code> / <code>IFRAME_CONTEXT</code> handshake flow.</p>
<label>
Username
<input id="username" value="+60777777777" />
<input id="username" value="+60333333333" />
</label>
<label>
Token
<input id="token" value="" readonly />
</label>
<label>
Language
<input id="language" value="zh-CN" />
<input id="language" value="zh-my" />
</label>
<div class="actions">
<button id="send" class="primary" type="button">Send Context</button>
<button id="send" class="primary" type="button">Fetch Token &amp; Send Context</button>
<button id="reload" class="secondary" type="button">Reload Iframe</button>
</div>
@@ -170,8 +175,8 @@
<script>
const frame = document.getElementById('playx-frame')
const previewFrame = document.getElementById('preview-frame')
const usernameInput = document.getElementById('username')
const tokenInput = document.getElementById('token')
const languageInput = document.getElementById('language')
const sendButton = document.getElementById('send')
const reloadButton = document.getElementById('reload')
@@ -182,6 +187,9 @@
const heightLogDelay = 300
let pendingHeightLog = null
let heightLogTimer = null
let currentTokenUsername = ''
let autoContextSent = false
let sendContextInFlight = false
function appendLog(message, data) {
const stamp = new Date().toLocaleTimeString()
@@ -200,7 +208,7 @@
}
heightLogTimer = window.setTimeout(() => {
appendLog('Received PLAYX_HEIGHT from iframe', pendingHeightLog)
appendLog('Received IFRAME_HEIGHT from iframe', pendingHeightLog)
pendingHeightLog = null
heightLogTimer = null
}, heightLogDelay)
@@ -210,35 +218,106 @@
return {
type: 'IFRAME_CONTEXT',
payload: {
username: usernameInput.value.trim(),
token: tokenInput.value.trim(),
language: languageInput.value.trim(),
},
}
}
function sendContext() {
async function ensureToken() {
const username = usernameInput.value.trim()
if (!username) {
throw new Error('Username is required.')
}
const existingToken = tokenInput.value.trim()
if (existingToken && currentTokenUsername === username) {
return existingToken
}
const response = await fetch(`/api/v1/temLogin?username=${encodeURIComponent(username)}`, {
method: 'GET',
})
if (!response.ok) {
throw new Error(`temLogin request failed: ${response.status}`)
}
const payload = await response.json()
const token = payload?.data?.userInfo?.token?.trim()
console.log('[test-host] temLogin response:', payload)
if (!token) {
throw new Error(`temLogin response missing token: ${JSON.stringify(payload)}`)
}
tokenInput.value = token
currentTokenUsername = username
appendLog('Fetched token from temLogin', {
username,
tokenPreview: `${token.slice(0, 12)}...`,
})
return token
}
async function sendContext() {
if (sendContextInFlight) {
return
}
sendContextInFlight = true
sendButton.disabled = true
try {
await ensureToken()
} catch (error) {
appendLog('Failed to fetch token', {
message: error instanceof Error ? error.message : String(error),
})
sendButton.disabled = false
sendContextInFlight = false
return
}
const message = buildPayload()
console.log('[test-host] postMessage payload:', message)
frame.contentWindow?.postMessage(message, iframeOrigin)
appendLog('Sent IFRAME_CONTEXT to iframe', {
language: message.payload.language,
tokenPreview: `${message.payload.token.slice(0, 12)}...`,
})
sendButton.disabled = false
sendContextInFlight = false
}
frame.addEventListener('load', () => {
autoContextSent = false
})
sendButton.addEventListener('click', () => {
sendContext()
sendButton.addEventListener('click', async () => {
await sendContext()
})
reloadButton.addEventListener('click', () => {
autoContextSent = false
frame.contentWindow?.location.reload()
})
window.addEventListener('message', (event) => {
if (event.source === frame.contentWindow && event.data?.type === 'PLAYX_READY') {
sendContext()
if (event.source === frame.contentWindow && event.data?.type === 'IFRAME_READY') {
appendLog('Received IFRAME_READY from iframe')
if (autoContextSent) {
return
}
autoContextSent = true
void sendContext()
return
}
if (event.source === frame.contentWindow && event.data?.type === 'PLAYX_HEIGHT') {
if (event.source === frame.contentWindow && event.data?.type === 'IFRAME_HEIGHT') {
const height = Number(event.data?.payload?.height)
if (!Number.isFinite(height) || height <= 0) {