Skip to content

JavaScript SDK 鉴权 ​

浏览器 SDK 使用短期令牌,每个令牌只能用于签发时指定的功能和模型。长期有效的 API Key 只保存在应用后端或你自己管理的设备中,不能出现在浏览器代码、打包后的文件、Web Storage、Cookie 或 URL 中。

获取令牌 ​

text
浏览器 SDK
  → 应用后端:当前调用所需的 clientId、scope 和 resource
  → Convbased:应用后端使用 API Key 换取短期 SDK 令牌
  ← 浏览器 SDK:仅返回 access_token

SDK 根据你调用的函数生成令牌请求:

字段值
clientId你为这个网页应用取的固定名称,不需要保密
scopes本次调用需要的权限,取 realtime、file_inference 或 tts 中的一项或多项
resource本次调用要使用的变声模型 { type: "vc_model", id: "model_xxx" } 或文本转语音 { type: "tts" }

应用后端必须检查请求中的 scopes 和 resource,只为当前用户有权使用的功能和模型签发令牌。

配置 tokenProvider ​

ts
import type { SdkAuthOptions } from "@convbased/sdk";

export const auth: SdkAuthOptions = {
  clientId: "example.web",
  tokenProvider: async (request) => {
    const response = await fetch("/api/convbased/sdk-token", {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify(request),
    });

    if (!response.ok) throw new Error("SDK token request failed");
    const result = (await response.json()) as { access_token: string };
    return result.access_token;
  },
};

clientId 必须以字母或数字开头,只使用字母、数字、点、下划线、冒号和连字符,最长 128 个字符。

应用后端 ​

在应用后端实现 /api/convbased/sdk-token 路由,按顺序处理请求:

  1. 确认当前登录的用户是谁;
  2. 检查该用户是否有权使用请求中的 scope 和 resource;
  3. 使用服务端 API Key 调用 Convbased 的 issueSdkToken;
  4. 只向浏览器返回短期 access_token。

调用 issueSdkToken 的后端示例:

ts
import type { SdkTokenRequest } from "@convbased/sdk";

const ISSUE_SDK_TOKEN = `
  mutation IssueSdkToken($input: IssueSdkTokenInput!) {
    issueSdkToken(input: $input) {
      access_token
    }
  }
`;

export async function exchangeSdkToken(request: SdkTokenRequest) {
  const response = await fetch("https://api.weights.chat/api/v1/graphql", {
    method: "POST",
    headers: {
      "content-type": "application/json",
      "x-api-key": process.env.API_KEY!,
    },
    body: JSON.stringify({
      query: ISSUE_SDK_TOKEN,
      variables: {
        input: {
          client_id: request.clientId,
          scopes: request.scopes,
          resource: request.resource,
          expires_in: 300,
        },
      },
    }),
  });

  const body = await response.json();
  const token = body.data?.issueSdkToken?.access_token;
  if (!response.ok || body.errors?.length || !token) {
    throw new Error("Convbased SDK token exchange failed");
  }
  return token as string;
}

确认用户身份和使用权限后,再调用 exchangeSdkToken()。API Key 自身的 scope 必须包含请求的权限,API Key 所属的账户必须能使用请求的模型。令牌有效期由 Convbased 服务端限制。

已签发令牌 ​

在自己的测试环境中,可以直接传入一个已经签发的令牌:

ts
const auth = {
  clientId: "example.web",
  sessionToken: issuedToken,
};

sessionToken 过期后不会自动更新,只能用于签发时指定的 scope 和 resource。正式上线的网页应用应使用 tokenProvider。

错误处理 ​

ts
import { SdkAuthError } from "@convbased/sdk";

try {
  await Convbased.startVoiceChange({ auth, modelId, output });
} catch (error) {
  if (error instanceof SdkAuthError) console.error(error.code);
}
代码含义处理
AUTH_REQUIRED、AUTH_INVALID_CREDENTIAL没有提供令牌,或令牌格式无效检查 tokenProvider 返回的内容,不要反复重试
AUTH_EXPIRED、AUTH_REVOKED令牌已过期,或签发它的 API Key 已失效让用户重新登录,或由 tokenProvider 重新申请令牌
AUTH_AUDIENCE_MISMATCH令牌不是为浏览器 SDK 签发的检查后端签发令牌时调用的接口
AUTH_SCOPE_FORBIDDEN、AUTH_RESOURCE_FORBIDDEN令牌不包含本次调用需要的 scope 或 resource检查用户权限和后端签发令牌时传入的参数
TOKEN_PROVIDER_FAILEDtokenProvider 调用失败按应用处理网络错误的方式处理