Trading Widget 認證

使用 Partner-Token 進行新的嵌入式交易 SSO 整合。

以 Markdown 格式查看

Partner-Token 避免在 URL 中放置短令牌,並將 apiSecret 留在 Partner 後端。

1const widget = TradingWidget.create('#trading-widget', {
2 baseUrl: 'https://app.6mm.com',
3 auth: {
4 mode: 'partner-token',
5 tokenProvider: async ({ channelId, symbol, reason }) => {
6 const resp = await fetch('/api/trading/embed-token', {
7 method: 'POST',
8 credentials: 'include',
9 headers: { 'Content-Type': 'application/json' },
10 body: JSON.stringify({ channelId, symbol, reason }),
11 })
12
13 if (!resp.ok) {
14 throw new Error('Failed to request embed token')
15 }
16
17 return resp.json()
18 },
19 },
20})
  • [建立嵌入令牌](/sdk/agent-sdk/java/embed-token):後端令牌發行範例。
  • [Trading Widget 快速啟動](/sdk/trading-widget/quick-start):完成初始化流程。
  • [秘密與簽署](/sdk/security/secrets-signing):將特權代理憑證保留在後端。
  • [故障排除](/sdk/security/troubleshooting):診斷會話、標記、起源及初始化失敗。

後端流程

1. Partner frontend receives auth_request from the iframe.
2. SDK calls tokenProvider.
3. Partner frontend calls its own backend.
4. Partner backend validates the partner session.
5. Partner backend calls 6MM Agent API or Java SDK createEmbedToken.
6. SDK sends embedToken to the iframe through postMessage.
7. iframe exchanges embedToken for a 6MM access token.
8. iframe continues initialization and emits ready.

tokenProvider 合約

場地導演描述
channelIdSDK -> 合作夥伴後端唯一的小工具會話識別碼。後端應該會把它傳給 createEmbedToken。
象徵SDK -> 合作夥伴後端目前請求的交易代碼。必要時用它來定位代幣。
原因SDK -> 合作夥伴後端為什麼 SDK 會請求一個代幣,例如初始載入或刷新。
embedToken合作夥伴後端 -> SDK由 Agent SDK 或代理人 API 產生的短暫代幣。
expireAt合作夥伴後端 -> SDK代幣過期時間戳由 6MM返回。

故障處理

狀況建議操作方法
夥伴會議結束從合作夥伴端點回傳 401 並要求使用者重新登入。
代幣創建暫時失敗在 tokenProvider 丟出錯誤,讓小工具顯示認證錯誤。
channelId 不匹配拒絕請求並重新建立小工具實例。
用戶不得進行交易回傳由夥伴控制的錯誤,且不建立嵌入標記。

相容模式:agent-sso

agent-SSO 保留舊版的 /agent-entry 工單流程。新整合時偏好 partner-token 。

1const widget = TradingWidget.create('#trading-widget', {
2 baseUrl: 'https://app.6mm.com',
3 auth: {
4 mode: 'agent-sso',
5 entryUrlProvider: async ({ redirectPath }) => {
6 const resp = await fetch('/api/trading-entry', {
7 method: 'POST',
8 credentials: 'include',
9 headers: { 'Content-Type': 'application/json' },
10 body: JSON.stringify({ redirectPath }),
11 })
12 const data = await resp.json()
13 return data.webUrl
14 },
15 },
16})