@ edge- markets/ 连接- 链接
EDGE连接弹出认证的浏览器 SDK.
特征
- 🔒 默认安全 - PKCE OAuth 流量,浏览器中没有客户端秘密
- 🚀 简单 API - 刚刚
new EdgeLink()财务报告和审定财务报表link.open() - 📱 到处都行 - 优雅地处理弹出障碍
- 📊 事件跟踪 - 说吧
onSuccess, (中文(简体) ),onExit, (中文(简体) ),onEvent调用 - 🎨 美丽的装载状态 - 专业品牌经验
- 📝 完整类型脚本 - 完整的类型定义
安装
npm install @edge-markets/connect-link
# or
pnpm add @edge-markets/connect-link
# or
yarn add @edge-markets/connect-link
快速启动
import { EdgeLink } from '@edge-markets/connect-link'
// 1. Create instance (do this once)
const link = new EdgeLink({
clientId: 'your-client-id',
environment: 'sandbox',
onSuccess: (result) => {
// Send to your backend for token exchange
fetch('/api/edge/exchange', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
code: result.code,
codeVerifier: result.codeVerifier,
}),
})
},
onExit: (metadata) => {
if (metadata.reason === 'popup_blocked') {
alert('Please allow popups for this site')
}
},
})
// 2. Open from a click handler
document.getElementById('connect-btn')!.onclick = () => link.open()
QQ 重要: 用户手势要求
link.open() 从用户点击处理器直接调用 MUST !
浏览器会阻断并非由用户交互所触发的弹出. 打电话前的任何同步工作 open() 将打破这个.
// ✅ Correct - direct click handler
button.onclick = () => link.open()
// ✅ Correct - immediate call in handler
button.onclick = () => {
trackClick() // sync ok
link.open()
}
// ❌ Wrong - async gap breaks user gesture
button.onclick = async () => {
await someAsyncWork() // breaks it!
link.open() // BLOCKED
}
// ❌ Wrong - setTimeout breaks user gesture
button.onclick = () => {
setTimeout(() => link.open(), 100) // BLOCKED
}
配置
interface EdgeLinkConfig {
// Required
clientId: string // Your OAuth client ID
environment: EdgeEnvironment // 'production' | 'sandbox'
onSuccess: (result) => void // Called on successful auth
// Optional
onExit?: (metadata) => void // Called when user exits
onEvent?: (event) => void // Called for analytics events
scopes?: EdgeScope[] // Scopes to request (default: all)
linkUrl?: string // Custom Link URL/origin (dev only)
redirectUri?: string // Legacy popup callback URI (migration only)
}
SDK 来自主机链接 URL environment; 沙盒默认为
https://sandbox-oauth.staging-app.edgeboost.io/oauth/link。 。 。 . linkUrl 仅需要用于
非标准部署。 如果作为来源提供,例如
https://oauth.example.com,SDK附件 /oauth/link。 。 。 .
弹出式整合基于起源. 用 EDGE 注册您的前端来源
页:1 postMessage 验证,例如:
https://app.partner.comhttp://localhost:3000http://localhost:5173
redirectUri 弹出完成不再需要。 留着吧
迁移一个仍然发送一个已注册回调 URL 的旧集成 .
回电
成功时
当用户成功认证并给予同意时调用 :
onSuccess: (result) => {
// result.code - Authorization code (send to backend)
// result.codeVerifier - PKCE verifier (send to backend)
// result.state - State parameter (for validation)
// IMPORTANT: Exchange tokens on your backend, not here!
// The backend has your client secret, the browser doesn't.
}
退出时
用户退出流量时调用 :
onExit: (metadata) => {
switch (metadata.reason) {
case 'user_closed':
// User closed the popup
break
case 'popup_blocked':
// Popup was blocked - show instructions
alert('Please allow popups')
break
case 'error':
// An error occurred
console.error(metadata.error?.message)
break
}
}
活动
调试分析 :
onEvent: (event) => {
// event.eventName - 'OPEN' | 'CLOSE' | 'HANDOFF' | 'SUCCESS' | 'ERROR'
// event.timestamp - Unix timestamp
// event.metadata - Additional context
analytics.track('edge_link_event', event)
}
方法
| 方法 | 说明 |
|---|---|
open(options?) | 打开链接弹出( 必须来自点击处理器) |
close() | 程序关闭弹出 |
destroy() | 清理资源(完成后调用) |
isOpen() | 弹出打开后返回真 |
范围
只请求您需要的权限 :
import { EdgeLink, EDGE_SCOPES } from '@edge-markets/connect-link'
const link = new EdgeLink({
clientId: 'your-client-id',
environment: 'sandbox',
scopes: [
EDGE_SCOPES.USER_READ, // Read profile
EDGE_SCOPES.BALANCE_READ, // Read balance
// EDGE_SCOPES.TRANSFER_WRITE is reserved and currently unavailable
],
onSuccess: handleSuccess,
})
反应钩
在反应中使用 EdgeLink 建议的方法 :
import { useEdgeLink } from '@edge-markets/connect-link'
function ConnectButton() {
const { open, ready, isOpen, error } = useEdgeLink({
clientId: process.env.NEXT_PUBLIC_EDGE_CLIENT_ID!,
environment: 'sandbox',
onSuccess: async (result) => {
await fetch('/api/edge/exchange', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(result),
})
},
onExit: (metadata) => {
if (metadata.reason === 'popup_blocked') {
alert('Please allow popups')
}
},
})
if (error) {
return <div>Error: {error.message}</div>
}
return (
<button onClick={() => open()} disabled={!ready || isOpen}>
{isOpen ? 'Connecting...' : 'Connect EdgeBoost'}
</button>
)
}
Hook 返回值
| 财产 | 类型 | 说明 |
|---|---|---|
open | (options?) => void | 打开链接弹出 |
ready | boolean | EdgeLink 初始化时为真 |
isOpen | boolean | 弹出时为真 |
error | Error | null | 初始化或运行时间出错 |
手动反应示例
为了获得更多的控制, 您可以直接使用 EdgeLink :
import { useEffect, useRef, useCallback } from 'react'
import { EdgeLink } from '@edge-markets/connect-link'
function ConnectButton() {
const linkRef = useRef<EdgeLink | null>(null)
useEffect(() => {
linkRef.current = new EdgeLink({
clientId: process.env.NEXT_PUBLIC_EDGE_CLIENT_ID!,
environment: 'sandbox',
onSuccess: async (result) => {
await fetch('/api/edge/exchange', {
method: 'POST',
body: JSON.stringify(result),
})
},
onExit: (metadata) => {
if (metadata.reason === 'popup_blocked') {
alert('Please allow popups')
}
},
})
return () => linkRef.current?.destroy()
}, [])
const handleClick = useCallback(() => {
linkRef.current?.open()
}, [])
return (
<button onClick={handleClick}>
Connect EdgeBoost
</button>
)
}
如何运作
- 用户单击按钮 →
link.open()名为 - 弹出即时打开 + 显示有品牌的装入状态
- PKCE 生成 - 安全OAuth没有客户秘密
- 弹出导航到链接页面 + 用户日志(同意)
- 通过邮件返回代码 · 安全的跨源通信
- 已调用成功 ~ 您将代码发送到后端以进行符号交换
┌─────────────┐ ┌─────────────────┐ ┌──────────────┐
│ Your App │ │ EdgeLink Popup │ │ Your Backend │
└──────┬──────┘ └────────┬────────┘ └──────┬───────┘
│ │ │
│ link.open() │ │
├────────────────────►│ │
│ │ │
│ (user logs in, grants consent) │
│ │ │
│ postMessage(code) │ │
│◄────────────────────┤ │
│ │ │
│ onSuccess(result) │ │
├─────────────────────┼────────────────────►│
│ │ POST /api/exchange │
│ │ │
│ │ tokens │
│◄────────────────────┼─────────────────────┤
│ │ │
警卫
- 捷克 - 防止授权代码拦截
- 状态参数 - 防止企业社会责任基金的袭击
- 来源验证 - 仅接受来自预期来源的邮件
- 浏览器中没有客户端秘密 - 在后端进行交换
相关软件包
@edge-markets/connect- 核心类型和公用事业@edge-markets/connect-node- 用于交换令牌的服务器 SDK
许可证
麻省理工学院