starchild-auth

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

🔑 Starchild Auth SDK

🔑 Starchild Auth SDK

Integrate Starchild OAuth login into any web application — React, Vue, or plain HTML. The SDK handles the full OAuth popup flow, token management, automatic refresh, and session restoration.
将Starchild OAuth登录集成到任意Web应用中——支持React、Vue或纯HTML项目。该SDK可处理完整的OAuth弹窗流程、令牌管理、自动刷新以及会话恢复。

When to Use

使用场景

  • Adding Starchild login to a web project
  • Implementing OAuth authentication with iamstarchild.com
  • Building a third-party app that needs Starchild user identity
  • Replacing a custom auth flow with Starchild SSO

  • 为Web项目添加Starchild登录功能
  • 基于iamstarchild.com实现OAuth身份验证
  • 开发需要获取Starchild用户身份的第三方应用
  • 使用Starchild单点登录替换自定义认证流程

Step 1 — Register Your App & Get Client ID

步骤1 — 注册应用并获取客户端ID

  1. Go to iamstarchild.com → click the More menu (left sidebar) → OAuth Apps
    • Direct link:
      https://iamstarchild.com/oauth-apps
  2. Click Create App
  3. Fill in:
    • App Name (required): your application name
    • Allowed Origin (required): the origin of your website (e.g.
      https://your-app.com
      ). For local development, use
      http://localhost:3000
      . Must be a valid origin — no paths, query params, or hash allowed. Non-localhost origins must use
      https://
      .
    • Description (optional): only visible to you
  4. After creation, a dialog will show your Client ID — copy it immediately
⚠️ Keep your Client ID safe. Never commit it directly in source code — use environment variables. Each user can create up to 10 OAuth apps.

  1. 访问 iamstarchild.com → 点击左侧侧边栏的更多菜单 → OAuth应用
    • 直接链接:
      https://iamstarchild.com/oauth-apps
  2. 点击创建应用
  3. 填写信息:
    • 应用名称(必填):你的应用名称
    • 允许的源地址(必填):你的网站源地址(例如
      https://your-app.com
      )。本地开发时使用
      http://localhost:3000
      。必须是有效的源地址——不允许包含路径、查询参数或哈希值。非本地主机的源地址必须使用
      https://
    • 描述(可选):仅对你可见
  4. 创建完成后,弹窗会显示你的客户端ID——请立即复制保存
⚠️ 请妥善保管你的客户端ID。切勿直接提交到源代码中——请使用环境变量存储。 每个用户最多可创建10个OAuth应用。

Step 2 — Install the SDK

步骤2 — 安装SDK

npm / yarn / pnpm

npm / yarn / pnpm

bash
undefined
bash
undefined

npm

npm

npm install starchild-auth-sdk
npm install starchild-auth-sdk

yarn

yarn

yarn add starchild-auth-sdk
yarn add starchild-auth-sdk

pnpm

pnpm

pnpm add starchild-auth-sdk
undefined
pnpm add starchild-auth-sdk
undefined

CDN (for plain HTML)

CDN(适用于纯HTML项目)

The SDK provides two builds. For plain
<script>
tags, use the UMD build:
html
<!-- unpkg (recommended) -->
<script src="https://unpkg.com/starchild-auth-sdk/dist/starchild-auth.umd.cjs"></script>

<!-- npmmirror (alternative, for China mainland) -->
<script src="https://registry.npmmirror.com/starchild-auth-sdk/latest/files/dist/starchild-auth.umd.cjs"></script>
⚠️ Do NOT use
starchild-auth.js
with a plain
<script>
tag — that file is an ES Module and will fail silently. Use
starchild-auth.umd.cjs
for
<script>
tags, or use
<script type="module">
with the ESM build (see examples below).
💡 CDN 加载失败? 如果两个 CDN 都无法访问(如在受限网络环境中),可以用
curl
下载到本地后通过相对路径引用:
bash
curl -sL "https://unpkg.com/starchild-auth-sdk/dist/starchild-auth.umd.cjs" -o starchild-auth.umd.cjs
然后
<script src="starchild-auth.umd.cjs"></script>
When loaded via UMD CDN, the class is available directly as
window.StarchildAuth
(it's the constructor itself, not a namespace object).

SDK提供两种构建版本。对于普通
<script>
标签,请使用UMD构建版本:
html
<!-- unpkg(推荐) -->
<script src="https://unpkg.com/starchild-auth-sdk/dist/starchild-auth.umd.cjs"></script>

<!-- npmmirror(备选,适用于中国大陆地区) -->
<script src="https://registry.npmmirror.com/starchild-auth-sdk/latest/files/dist/starchild-auth.umd.cjs"></script>
⚠️ 请勿
starchild-auth.js
用于普通
<script>
标签——该文件是ES模块,会静默失败。对于
<script>
标签,请使用
starchild-auth.umd.cjs
,或结合ESM构建版本使用
<script type="module">
(见下方示例)。
💡 CDN 加载失败? 如果两个CDN都无法访问(如受限网络环境),可以使用
curl
下载到本地后通过相对路径引用:
bash
curl -sL "https://unpkg.com/starchild-auth-sdk/dist/starchild-auth.umd.cjs" -o starchild-auth.umd.cjs
然后使用
<script src="starchild-auth.umd.cjs"></script>
通过UMD CDN加载后,类将直接作为
window.StarchildAuth
可用(它本身是构造函数,而非命名空间对象)。

Step 3 — Initialize the SDK

步骤3 — 初始化SDK

typescript
import { StarchildAuth } from 'starchild-auth-sdk'

const auth = new StarchildAuth({
  clientId: 'your-client-id',

  // Called after successful login (popup or auto-login session restore)
  onLogin: ({ accessToken, refreshToken, expiresIn, userInfo }) => {
    console.log('Logged in:', userInfo.agentName)
    console.log('Avatar:', userInfo.agentAvatar)
  },

  // Called after logout
  onLogout: () => {
    console.log('Logged out')
  },

  // Token auto-refreshes every 12 minutes
  onTokenRefresh: (newAccessToken) => {
    console.log('Token refreshed')
  },

  // Called when refresh fails (session expired)
  onTokenRefreshFailed: () => {
    console.log('Session expired, please log in again')
  },
})
Auto-login: By default (
autoLogin: true
), the SDK checks localStorage for a stored refresh token on initialization and automatically restores the session. This means
onLogin
may fire immediately after construction without calling
login()
.

typescript
import { StarchildAuth } from 'starchild-auth-sdk'

const auth = new StarchildAuth({
  clientId: 'your-client-id',

  // 登录成功后调用(弹窗登录或自动登录恢复会话时)
  onLogin: ({ accessToken, refreshToken, expiresIn, userInfo }) => {
    console.log('Logged in:', userInfo.agentName)
    console.log('Avatar:', userInfo.agentAvatar)
  },

  // 登出后调用
  onLogout: () => {
    console.log('Logged out')
  },

  // 令牌每12分钟自动刷新
  onTokenRefresh: (newAccessToken) => {
    console.log('Token refreshed')
  },

  // 刷新失败时调用(会话过期)
  onTokenRefreshFailed: () => {
    console.log('Session expired, please log in again')
  },
})
自动登录:默认情况下(
autoLogin: true
),SDK初始化时会检查localStorage中存储的刷新令牌,并自动恢复会话。这意味着无需调用
login()
onLogin
可能会在实例创建后立即触发。

Step 4 — Login / Logout / Status

步骤4 — 登录/登出/状态检查

typescript
// Trigger login (opens Starchild OAuth popup)
const { accessToken, refreshToken, expiresIn, userInfo } = await auth.login()

// Logout (clears tokens, revokes refresh token via API)
await auth.logout()

// Check login status
const isLoggedIn: boolean = auth.isLoggedIn()

// Get current access token (null if not logged in)
const token: string | null = auth.getToken()

// Get current user info (null if not logged in)
const user: UserInfo | null = auth.getUserInfo()
// user = { userInfoId: string, agentName: string, agentAvatar: string }

// Manually trigger token refresh (normally automatic every 12 min)
const newToken: string = await auth.refreshToken()

// Destroy instance (remove listeners, clear timers, clear tokens)
auth.destroy()

typescript
// 触发登录(打开Starchild OAuth弹窗)
const { accessToken, refreshToken, expiresIn, userInfo } = await auth.login()

// 登出(清除令牌,通过API撤销刷新令牌)
await auth.logout()

// 检查登录状态
const isLoggedIn: boolean = auth.isLoggedIn()

// 获取当前访问令牌(未登录时返回null)
const token: string | null = auth.getToken()

// 获取当前用户信息(未登录时返回null)
const user: UserInfo | null = auth.getUserInfo()
// user = { userInfoId: string, agentName: string, agentAvatar: string }

// 手动触发令牌刷新(通常每12分钟自动刷新)
const newToken: string = await auth.refreshToken()

// 销毁实例(移除监听器、清除定时器、清除令牌)
auth.destroy()

Framework Examples

框架示例

React

React

tsx
// src/hooks/useStarchildAuth.ts
import { useState, useEffect, useRef, useCallback } from 'react'
import { StarchildAuth } from 'starchild-auth-sdk'
import type { UserInfo, LoginResult } from 'starchild-auth-sdk'

export function useStarchildAuth() {
  const [user, setUser] = useState<UserInfo | null>(null)
  const [token, setToken] = useState<string | null>(null)
  const [loading, setLoading] = useState(true)
  const authRef = useRef<StarchildAuth | null>(null)

  useEffect(() => {
    const auth = new StarchildAuth({
      clientId: import.meta.env.VITE_STARCHILD_CLIENT_ID,
      onLogin: ({ accessToken, userInfo }: LoginResult) => {
        setUser(userInfo)
        setToken(accessToken)
        setLoading(false)
      },
      onLogout: () => {
        setUser(null)
        setToken(null)
      },
      onTokenRefresh: (newToken: string) => {
        setToken(newToken)
      },
      onTokenRefreshFailed: () => {
        setUser(null)
        setToken(null)
      },
      // autoLogin: true (default) — will restore session from localStorage
    })

    authRef.current = auth

    // If auto-login doesn't fire onLogin (no stored session), stop loading
    const timeout = setTimeout(() => setLoading(false), 1500)

    return () => {
      clearTimeout(timeout)
      auth.destroy()
    }
  }, [])

  const login = useCallback(async () => {
    if (!authRef.current) return
    return await authRef.current.login()
  }, [])

  const logout = useCallback(async () => {
    if (!authRef.current) return
    await authRef.current.logout()
  }, [])

  return { user, token, loading, login, logout, isLoggedIn: !!user }
}
tsx
// src/App.tsx
import { useStarchildAuth } from './hooks/useStarchildAuth'

function App() {
  const { user, loading, login, logout, isLoggedIn } = useStarchildAuth()

  if (loading) return <div>Loading...</div>

  return (
    <div>
      {isLoggedIn ? (
        <div>
          <p>Welcome, {user?.agentName}</p>
          <img src={user?.agentAvatar} alt="avatar" width={40} />
          <button onClick={logout}>Logout</button>
        </div>
      ) : (
        <button onClick={login}>Login with Starchild</button>
      )}
    </div>
  )
}

export default App
tsx
// src/hooks/useStarchildAuth.ts
import { useState, useEffect, useRef, useCallback } from 'react'
import { StarchildAuth } from 'starchild-auth-sdk'
import type { UserInfo, LoginResult } from 'starchild-auth-sdk'

export function useStarchildAuth() {
  const [user, setUser] = useState<UserInfo | null>(null)
  const [token, setToken] = useState<string | null>(null)
  const [loading, setLoading] = useState(true)
  const authRef = useRef<StarchildAuth | null>(null)

  useEffect(() => {
    const auth = new StarchildAuth({
      clientId: import.meta.env.VITE_STARCHILD_CLIENT_ID,
      onLogin: ({ accessToken, userInfo }: LoginResult) => {
        setUser(userInfo)
        setToken(accessToken)
        setLoading(false)
      },
      onLogout: () => {
        setUser(null)
        setToken(null)
      },
      onTokenRefresh: (newToken: string) => {
        setToken(newToken)
      },
      onTokenRefreshFailed: () => {
        setUser(null)
        setToken(null)
      },
      // autoLogin: true(默认值)——将从localStorage恢复会话
    })

    authRef.current = auth

    // 如果自动登录未触发onLogin(无存储会话),停止加载状态
    const timeout = setTimeout(() => setLoading(false), 1500)

    return () => {
      clearTimeout(timeout)
      auth.destroy()
    }
  }, [])

  const login = useCallback(async () => {
    if (!authRef.current) return
    return await authRef.current.login()
  }, [])

  const logout = useCallback(async () => {
    if (!authRef.current) return
    await authRef.current.logout()
  }, [])

  return { user, token, loading, login, logout, isLoggedIn: !!user }
}
tsx
// src/App.tsx
import { useStarchildAuth } from './hooks/useStarchildAuth'

function App() {
  const { user, loading, login, logout, isLoggedIn } = useStarchildAuth()

  if (loading) return <div>Loading...</div>

  return (
    <div>
      {isLoggedIn ? (
        <div>
          <p>Welcome, {user?.agentName}</p>
          <img src={user?.agentAvatar} alt="avatar" width={40} />
          <button onClick={logout}>Logout</button>
        </div>
      ) : (
        <button onClick={login}>Login with Starchild</button>
      )}
    </div>
  )
}

export default App

Vue 3 (Composition API)

Vue 3(组合式API)

typescript
// src/composables/useStarchildAuth.ts
import { ref, onMounted, onUnmounted } from 'vue'
import { StarchildAuth } from 'starchild-auth-sdk'
import type { UserInfo, LoginResult } from 'starchild-auth-sdk'

export function useStarchildAuth() {
  const user = ref<UserInfo | null>(null)
  const token = ref<string | null>(null)
  const loading = ref(true)
  let authInstance: StarchildAuth | null = null

  onMounted(() => {
    authInstance = new StarchildAuth({
      clientId: import.meta.env.VITE_STARCHILD_CLIENT_ID,
      onLogin: ({ accessToken, userInfo }: LoginResult) => {
        user.value = userInfo
        token.value = accessToken
        loading.value = false
      },
      onLogout: () => {
        user.value = null
        token.value = null
      },
      onTokenRefresh: (newToken: string) => {
        token.value = newToken
      },
      onTokenRefreshFailed: () => {
        user.value = null
        token.value = null
      },
    })

    // If no stored session, stop loading after timeout
    setTimeout(() => { loading.value = false }, 1500)
  })

  onUnmounted(() => {
    authInstance?.destroy()
  })

  const login = async () => {
    if (!authInstance) return
    return await authInstance.login()
  }

  const logout = async () => {
    if (!authInstance) return
    await authInstance.logout()
  }

  const isLoggedIn = () => !!user.value

  return { user, token, loading, login, logout, isLoggedIn }
}
vue
<!-- src/App.vue -->
<template>
  <div v-if="loading">Loading...</div>
  <div v-else-if="user">
    <p>Welcome, {{ user.agentName }}</p>
    <img :src="user.agentAvatar" alt="avatar" width="40" />
    <button @click="logout">Logout</button>
  </div>
  <div v-else>
    <button @click="login">Login with Starchild</button>
  </div>
</template>

<script setup lang="ts">
import { useStarchildAuth } from './composables/useStarchildAuth'

const { user, loading, login, logout } = useStarchildAuth()
</script>
typescript
// src/composables/useStarchildAuth.ts
import { ref, onMounted, onUnmounted } from 'vue'
import { StarchildAuth } from 'starchild-auth-sdk'
import type { UserInfo, LoginResult } from 'starchild-auth-sdk'

export function useStarchildAuth() {
  const user = ref<UserInfo | null>(null)
  const token = ref<string | null>(null)
  const loading = ref(true)
  let authInstance: StarchildAuth | null = null

  onMounted(() => {
    authInstance = new StarchildAuth({
      clientId: import.meta.env.VITE_STARCHILD_CLIENT_ID,
      onLogin: ({ accessToken, userInfo }: LoginResult) => {
        user.value = userInfo
        token.value = accessToken
        loading.value = false
      },
      onLogout: () => {
        user.value = null
        token.value = null
      },
      onTokenRefresh: (newToken: string) => {
        token.value = newToken
      },
      onTokenRefreshFailed: () => {
        user.value = null
        token.value = null
      },
    })

    // 如果无存储会话,超时后停止加载
    setTimeout(() => { loading.value = false }, 1500)
  })

  onUnmounted(() => {
    authInstance?.destroy()
  })

  const login = async () => {
    if (!authInstance) return
    return await authInstance.login()
  }

  const logout = async () => {
    if (!authInstance) return
    await authInstance.logout()
  }

  const isLoggedIn = () => !!user.value

  return { user, token, loading, login, logout, isLoggedIn }
}
vue
<!-- src/App.vue -->
<template>
  <div v-if="loading">Loading...</div>
  <div v-else-if="user">
    <p>Welcome, {{ user.agentName }}</p>
    <img :src="user.agentAvatar" alt="avatar" width="40" />
    <button @click="logout">Logout</button>
  </div>
  <div v-else>
    <button @click="login">Login with Starchild</button>
  </div>
</template>

<script setup lang="ts">
import { useStarchildAuth } from './composables/useStarchildAuth'

const { user, loading, login, logout } = useStarchildAuth()
</script>

Plain HTML — UMD (recommended for
<script>
tags)

纯HTML — UMD(推荐用于
<script>
标签)

💡 如果 CDN 加载失败,参考上方 Step 2 中的 CDN 备选源和本地下载方案。
html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Starchild Auth Demo</title>
  <!-- UMD build: works with plain <script> tags -->
  <!-- If CDN is blocked, download the file locally and use a relative path instead -->
  <script src="https://unpkg.com/starchild-auth-sdk/dist/starchild-auth.umd.cjs"></script>
</head>
<body>
  <div id="app">
    <div id="logged-out">
      <button id="login-btn">Login with Starchild</button>
    </div>
    <div id="logged-in" style="display: none">
      <p>Welcome, <span id="user-name"></span></p>
      <img id="user-avatar" width="40" />
      <button id="logout-btn">Logout</button>
    </div>
  </div>

  <script>
    // UMD exposes window.StarchildAuth as the constructor directly
    if (typeof window.StarchildAuth !== 'function') {
      document.getElementById('logged-out').innerHTML =
        '<p style="color:red">SDK failed to load. Check if the CDN script loaded correctly.</p>'
      throw new Error('StarchildAuth SDK not loaded')
    }

    var auth = new StarchildAuth({
      clientId: 'your-client-id',
      onLogin: function (result) {
        showLoggedIn(result.userInfo)
      },
      onLogout: function () {
        showLoggedOut()
      },
      onTokenRefresh: function (newToken) {
        console.log('Token refreshed')
      },
      onTokenRefreshFailed: function () {
        showLoggedOut()
      },
      // autoLogin: true (default) — restores session automatically
    })

    document.getElementById('login-btn').addEventListener('click', async function () {
      try {
        await auth.login()
      } catch (err) {
        console.error('Login failed:', err.message)
      }
    })

    document.getElementById('logout-btn').addEventListener('click', async function () {
      await auth.logout()
    })

    function showLoggedIn(user) {
      document.getElementById('logged-out').style.display = 'none'
      document.getElementById('logged-in').style.display = 'block'
      document.getElementById('user-name').textContent = user.agentName
      if (user.agentAvatar) {
        document.getElementById('user-avatar').src = user.agentAvatar
      }
    }

    function showLoggedOut() {
      document.getElementById('logged-out').style.display = 'block'
      document.getElementById('logged-in').style.display = 'none'
    }
  </script>
</body>
</html>
💡 如果CDN加载失败,请参考步骤2中的CDN备选源和本地下载方案。
html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Starchild Auth Demo</title>
  <!-- UMD构建版本:适用于普通<script>标签 -->
  <!-- 如果CDN被屏蔽,可下载文件到本地并使用相对路径 -->
  <script src="https://unpkg.com/starchild-auth-sdk/dist/starchild-auth.umd.cjs"></script>
</head>
<body>
  <div id="app">
    <div id="logged-out">
      <button id="login-btn">Login with Starchild</button>
    </div>
    <div id="logged-in" style="display: none">
      <p>Welcome, <span id="user-name"></span></p>
      <img id="user-avatar" width="40" />
      <button id="logout-btn">Logout</button>
    </div>
  </div>

  <script>
    // UMD版本直接暴露window.StarchildAuth作为构造函数
    if (typeof window.StarchildAuth !== 'function') {
      document.getElementById('logged-out').innerHTML =
        '<p style="color:red">SDK加载失败,请检查CDN脚本是否正确加载。</p>'
      throw new Error('StarchildAuth SDK not loaded')
    }

    var auth = new StarchildAuth({
      clientId: 'your-client-id',
      onLogin: function (result) {
        showLoggedIn(result.userInfo)
      },
      onLogout: function () {
        showLoggedOut()
      },
      onTokenRefresh: function (newToken) {
        console.log('Token refreshed')
      },
      onTokenRefreshFailed: function () {
        showLoggedOut()
      },
      // autoLogin: true(默认值)——自动恢复会话
    })

    document.getElementById('login-btn').addEventListener('click', async function () {
      try {
        await auth.login()
      } catch (err) {
        console.error('Login failed:', err.message)
      }
    })

    document.getElementById('logout-btn').addEventListener('click', async function () {
      await auth.logout()
    })

    function showLoggedIn(user) {
      document.getElementById('logged-out').style.display = 'none'
      document.getElementById('logged-in').style.display = 'block'
      document.getElementById('user-name').textContent = user.agentName
      if (user.agentAvatar) {
        document.getElementById('user-avatar').src = user.agentAvatar
      }
    }

    function showLoggedOut() {
      document.getElementById('logged-out').style.display = 'block'
      document.getElementById('logged-in').style.display = 'none'
    }
  </script>
</body>
</html>

Plain HTML — ES Module (alternative)

纯HTML — ES模块(备选)

If you prefer ES Module syntax, use
<script type="module">
:
html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Starchild Auth Demo (ESM)</title>
</head>
<body>
  <button id="login-btn">Login with Starchild</button>
  <div id="logged-in" style="display: none">
    <p>Welcome, <span id="user-name"></span></p>
    <button id="logout-btn">Logout</button>
  </div>

  <script type="module">
    import { StarchildAuth } from 'https://unpkg.com/starchild-auth-sdk/dist/starchild-auth.js'

    const auth = new StarchildAuth({
      clientId: 'your-client-id',
      onLogin: ({ userInfo }) => {
        document.getElementById('login-btn').style.display = 'none'
        document.getElementById('logged-in').style.display = 'block'
        document.getElementById('user-name').textContent = userInfo.agentName
      },
      onLogout: () => {
        document.getElementById('login-btn').style.display = 'block'
        document.getElementById('logged-in').style.display = 'none'
      },
    })

    document.getElementById('login-btn').addEventListener('click', () => auth.login())
    document.getElementById('logout-btn').addEventListener('click', () => auth.logout())
  </script>
</body>
</html>

如果你偏好ES模块语法,请使用
<script type="module">
html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Starchild Auth Demo (ESM)</title>
</head>
<body>
  <button id="login-btn">Login with Starchild</button>
  <div id="logged-in" style="display: none">
    <p>Welcome, <span id="user-name"></span></p>
    <button id="logout-btn">Logout</button>
  </div>

  <script type="module">
    import { StarchildAuth } from 'https://unpkg.com/starchild-auth-sdk/dist/starchild-auth.js'

    const auth = new StarchildAuth({
      clientId: 'your-client-id',
      onLogin: ({ userInfo }) => {
        document.getElementById('login-btn').style.display = 'none'
        document.getElementById('logged-in').style.display = 'block'
        document.getElementById('user-name').textContent = userInfo.agentName
      },
      onLogout: () => {
        document.getElementById('login-btn').style.display = 'block'
        document.getElementById('logged-in').style.display = 'none'
      },
    })

    document.getElementById('login-btn').addEventListener('click', () => auth.login())
    document.getElementById('logout-btn').addEventListener('click', () => auth.logout())
  </script>
</body>
</html>

API Reference

API参考

StarchildAuthOptions
(Constructor Options)

StarchildAuthOptions
(构造函数选项)

OptionTypeDefaultDescription
clientId
string
(required)OAuth Client ID from iamstarchild.com
onLogin
(result: LoginResult) => void
Called after successful login (popup or auto-login)
onLogout
() => void
Called after logout
onTokenRefresh
(accessToken: string) => void
Called when token is auto-refreshed
onTokenRefreshFailed
() => void
Called when token refresh fails (session expired)
autoLogin
boolean
true
Attempt to restore session from localStorage on init
origin
string
'https://iamstarchild.com'
Starchild origin URL (for popup login page)
apiBase
string
'https://go-api.iamstarchild.com/v1'
Go API base URL (for token refresh & logout)
chatApiBase
string
'https://ai-api.iamstarchild.com'
AI API base URL (for
/v1/oauth/userinfo
)
popupWidth
number
480
Login popup width in pixels
popupHeight
number
640
Login popup height in pixels
refreshInterval
number
720000
Auto-refresh interval in ms (default: 12 minutes)
选项类型默认值描述
clientId
string
必填来自iamstarchild.com的OAuth客户端ID
onLogin
(result: LoginResult) => void
登录成功后调用(弹窗登录或自动登录时)
onLogout
() => void
登出后调用
onTokenRefresh
(accessToken: string) => void
令牌自动刷新后调用
onTokenRefreshFailed
() => void
令牌刷新失败时调用(会话过期)
autoLogin
boolean
true
初始化时尝试从localStorage恢复会话
origin
string
'https://iamstarchild.com'
Starchild源地址(用于弹窗登录页面)
apiBase
string
'https://go-api.iamstarchild.com/v1'
Go API基础地址(用于令牌刷新和登出)
chatApiBase
string
'https://ai-api.iamstarchild.com'
AI API基础地址(用于
/v1/oauth/userinfo
popupWidth
number
480
登录弹窗宽度(像素)
popupHeight
number
640
登录弹窗高度(像素)
refreshInterval
number
720000
自动刷新间隔(毫秒,默认:12分钟)

Methods

方法

MethodReturnsDescription
login()
Promise<LoginResult>
Opens OAuth popup and returns credentials on success
logout()
Promise<void>
Clears session, revokes refresh token via API
isLoggedIn()
boolean
Whether user is currently authenticated
getToken()
string | null
Current access token, or
null
getUserInfo()
UserInfo | null
Current user info, or
null
refreshToken()
Promise<string>
Manually trigger token refresh, returns new access token
destroy()
void
Remove listeners, clear timers, clear tokens. Instance cannot be reused.
方法返回值描述
login()
Promise<LoginResult>
打开OAuth弹窗,成功时返回凭证信息
logout()
Promise<void>
清除会话,通过API撤销刷新令牌
isLoggedIn()
boolean
用户当前是否已认证
getToken()
string | null
当前访问令牌,未登录时返回
null
getUserInfo()
UserInfo | null
当前用户信息,未登录时返回
null
refreshToken()
Promise<string>
手动触发令牌刷新,返回新的访问令牌
destroy()
void
移除监听器、清除定时器、清除令牌。实例无法重复使用。

LoginResult
Type

LoginResult
类型

typescript
interface LoginResult {
  accessToken: string
  refreshToken: string
  expiresIn: number
  userInfo: UserInfo
}
typescript
interface LoginResult {
  accessToken: string
  refreshToken: string
  expiresIn: number
  userInfo: UserInfo
}

UserInfo
Type

UserInfo
类型

typescript
interface UserInfo {
  /** Unique user ID */
  userInfoId: string
  /** Display name (agent name) */
  agentName: string
  /** Avatar URL */
  agentAvatar: string
}
typescript
interface UserInfo {
  /** 唯一用户ID */
  userInfoId: string
  /** 显示名称(agent名称) */
  agentName: string
  /** 头像URL */
  agentAvatar: string
}

Token Lifecycle

令牌生命周期

  • Access tokens are short-lived and auto-refresh every 12 minutes (configurable via
    refreshInterval
    )
  • The SDK stores the refresh token in
    localStorage
    (key:
    starchild_rt_{clientId}
    )
  • On page reload, if
    autoLogin
    is
    true
    (default), the SDK uses the stored refresh token to restore the session automatically —
    onLogin
    fires again with fresh tokens
  • When the page returns from background (visibility change), the SDK automatically refreshes the token
  • If refresh fails (e.g. user revoked access, token expired),
    onTokenRefreshFailed
    fires and the stored refresh token is cleared

  • 访问令牌有效期短,每12分钟自动刷新(可通过
    refreshInterval
    配置)
  • SDK将刷新令牌存储在
    localStorage
    中(键名:
    starchild_rt_{clientId}
  • 页面刷新时,如果
    autoLogin
    true
    (默认值),SDK会使用存储的刷新令牌自动恢复会话——
    onLogin
    会再次触发并返回新令牌
  • 页面从后台恢复可见性时,SDK会自动刷新令牌
  • 如果刷新失败(例如用户撤销权限、令牌过期),
    onTokenRefreshFailed
    会触发,并清除存储的刷新令牌

Sending Authenticated API Requests

发送已认证的API请求

Once logged in, include the access token in your API requests:
typescript
const response = await fetch('https://api.your-app.com/data', {
  headers: {
    Authorization: `Bearer ${auth.getToken()}`,
  },
})
For React / Vue, use the
token
from the hook/composable:
typescript
// React example
const { token } = useStarchildAuth()

const fetchData = async () => {
  const res = await fetch('/api/data', {
    headers: { Authorization: `Bearer ${token}` },
  })
  return res.json()
}

登录成功后,在API请求中包含访问令牌:
typescript
const response = await fetch('https://api.your-app.com/data', {
  headers: {
    Authorization: `Bearer ${auth.getToken()}`,
  },
})
对于React / Vue项目,使用钩子/组合式函数中的
token
typescript
// React示例
const { token } = useStarchildAuth()

const fetchData = async () => {
  const res = await fetch('/api/data', {
    headers: { Authorization: `Bearer ${token}` },
  })
  return res.json()
}

Important Notes

重要注意事项

CDN Build Selection

CDN构建版本选择

BuildFileUsage
UMD
starchild-auth.umd.cjs
<script>
tags — exposes
window.StarchildAuth
(constructor)
ESM
starchild-auth.js
<script type="module">
or bundlers (Vite, webpack, etc.)
Common mistake: Using
starchild-auth.js
with a plain
<script>
tag. This will fail silently because the ESM file uses
export
syntax which is invalid in non-module scripts. Always use the
.umd.cjs
build for plain
<script>
tags.
构建版本文件使用场景
UMD
starchild-auth.umd.cjs
<script>
标签——暴露
window.StarchildAuth
(构造函数)
ESM
starchild-auth.js
<script type="module">
或打包工具(Vite、webpack等)
常见错误:将
starchild-auth.js
用于普通
<script>
标签。这会静默失败,因为ESM文件使用
export
语法,在非模块脚本中无效。对于普通
<script>
标签,请始终使用
.umd.cjs
构建版本。

Session Persistence

会话持久化

The SDK stores the refresh token in
localStorage
under the key
starchild_rt_{clientId}
. This enables:
  • Auto-login on page reload — no need to call
    login()
    again
  • Cross-tab session sharing — all tabs with the same
    clientId
    share the session
To fully clear a user's session, call
auth.logout()
which removes the stored token and revokes it server-side.

SDK将刷新令牌存储在
localStorage
中,键名为
starchild_rt_{clientId}
。这实现了:
  • 页面刷新时自动登录——无需再次调用
    login()
  • 跨标签页会话共享——所有使用相同
    clientId
    的标签页共享会话
要完全清除用户会话,请调用
auth.logout()
,它会移除存储的令牌并在服务器端撤销该令牌。

Troubleshooting

故障排除

IssueSolution
Popup blockedEnsure
login()
is called from a user gesture (click handler). Browsers block popups not triggered by user interaction.
Origin mismatchVerify the Allowed Origin in OAuth Apps settings matches your site's origin exactly (e.g.
https://your-app.com
). No trailing slash, no path.
StarchildAuth is not defined
(CDN)
You're using the ESM build (
starchild-auth.js
) with a plain
<script>
tag. Switch to the UMD build (
starchild-auth.umd.cjs
), or use
<script type="module">
with
import
.
Token refresh failingCheck that the app hasn't been revoked in user's Starchild settings. Also check browser console for network errors.
onLogin
fires on page load
This is expected behavior —
autoLogin: true
(default) restores the session from localStorage. Set
autoLogin: false
to disable.
CDN blockedunpkg.com may be slow/blocked in some environments. Use
npmmirror
as alternative (
https://registry.npmmirror.com/starchild-auth-sdk/latest/files/dist/starchild-auth.umd.cjs
), or download the SDK file locally and serve it from your own domain.
问题解决方案
弹窗被拦截确保
login()
从用户交互(如点击事件处理函数)中调用。浏览器会拦截非用户触发的弹窗。
源地址不匹配验证OAuth应用设置中的允许的源地址与你的网站源地址完全一致(例如
https://your-app.com
)。无尾部斜杠,无路径。
StarchildAuth is not defined
(CDN)
你正在将ESM构建版本(
starchild-auth.js
)用于普通
<script>
标签。切换到UMD构建版本(
starchild-auth.umd.cjs
),或结合
import
使用
<script type="module">
令牌刷新失败检查用户是否在Starchild设置中撤销了应用权限。同时查看浏览器控制台的网络错误信息。
onLogin
在页面加载时触发
这是预期行为——
autoLogin: true
(默认值)会从localStorage恢复会话。设置
autoLogin: false
可禁用此功能。
CDN被屏蔽unpkg.com在某些环境中可能加载缓慢或被屏蔽。使用npmmirror作为备选(
https://registry.npmmirror.com/starchild-auth-sdk/latest/files/dist/starchild-auth.umd.cjs
),或下载SDK文件到本地并从自己的域名提供服务。