Skip to content

鉴权

浏览器 SDK 使用短期访问令牌。应用只需提供 tokenProvider:SDK 在调用某项能力时把所需权限交给 provider,provider 向你的后端请求令牌并返回字符串。

应用不需要解析令牌;SDK 负责其余凭据生命周期。

配置 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 是当前浏览器集成的稳定标识。SDK 会按实际调用生成 request

字段含义
clientIdauth.clientId 相同。
scopes本次调用需要的能力:realtimefile_inferencetts
resource实时/文件变声对应模型,文本转语音对应 TTS 能力。

前端不应自行扩大 scopes 或改写 resource

后端职责

/api/convbased/sdk-token 是你的应用后端接口,不是 SDK 内置端点。后端需要:

  1. 识别当前应用用户。
  2. 校验该用户是否可以使用请求中的能力和资源。
  3. 使用服务端凭据向 Convbased 申请短期 SDK 令牌。
  4. 只把 access_token 返回给前端。

兑换使用公开 GraphQL mutation:

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

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

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.CONVBASED_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 || !token) {
    throw new Error("Convbased SDK token exchange failed");
  }
  return token;
}

先完成你自己的用户鉴权和能力授权,再调用 exchangeSdkToken。长期凭据不得出现在浏览器代码、构建产物或公开 URL 中;用户识别方式与服务端密钥管理不属于 SDK 契约。

已签发令牌

手动测试时,也可以直接传入已签发的 sessionToken

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

sessionToken 不能自动续期,并且只能用于它获准的能力和资源。生产接入使用 tokenProvider

处理鉴权错误

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

try {
  await Convbased.startVoiceChange({ auth, modelId, output });
} catch (error) {
  if (error instanceof SdkAuthError) {
    console.error(error.code);
  }
}
code含义建议处理
AUTH_REQUIREDAUTH_INVALID_CREDENTIAL缺少凭据或返回值无效。检查 provider 响应,不要循环重试。
AUTH_EXPIREDAUTH_REVOKED令牌已过期或撤销。让 provider 重新申请;持续失败时要求重新登录。
AUTH_AUDIENCE_MISMATCH令牌不属于浏览器 SDK。检查后端签发入口。
AUTH_SCOPE_FORBIDDENAUTH_RESOURCE_FORBIDDEN令牌未授权当前能力或资源。修正后端授权,不能靠重试解决。
TOKEN_PROVIDER_FAILEDprovider 请求失败。按应用网络错误策略处理。