跳到正文
Indiana
控制台
开发文档
章节目录 / 客户与会话

客户与会话

创建与更新 Customer,签发 Customer Token,处理访客与登录后认领。

API v1更新于

创建或查找 Customer

用你系统里已验证的用户 ID 作为 externalUserId。同一个 ID 再次调用会返回同一个 Customer(created: false),已有资料不会被覆盖。

customer.tsTypeScript
import { createIndianaServer } from "@tinkerlandai/indiana-sdk/server"; const indiana = createIndianaServer({  baseUrl: process.env.INDIANA_API_URL!,  apiKey: process.env.INDIANA_API_KEY!,  scope: { projectId: process.env.INDIANA_PROJECT_ID!, environment: "sandbox" },}); async function main() {  const { customer, created } = await indiana.getOrCreateCustomer({    externalUserId: "user-42",  });  console.log(customer.id, created);} main().catch((error) => {  console.error(error);  process.exitCode = 1;});

更新 Customer

只发送要修改的字段。每次更新生成一个 requestId 并保存;重试时使用同一个值,不会重复修改。

customer.tsTypeScript
import { createIndianaServer } from "@tinkerlandai/indiana-sdk/server"; const indiana = createIndianaServer({  baseUrl: process.env.INDIANA_API_URL!,  apiKey: process.env.INDIANA_API_KEY!,  scope: { projectId: process.env.INDIANA_PROJECT_ID!, environment: "sandbox" },}); export async function syncProfile(input: {  verifiedUserId: string;  requestId: string; // persisted before the first attempt  plan: string;}) {  const { customer, changed } = await indiana.updateCustomer({    lookup: { type: "externalUserId", value: input.verifiedUserId },    requestId: input.requestId,    patch: {      attributes: { plan: input.plan },      tagChanges: { add: ["beta"], remove: [] },    },  });  return { customerId: customer.id, changed };}

让浏览器直接调用

  • 后端验证用户登录后,调用 createCustomerSession 签发 Customer Token。
  • 浏览器调用 identify(token),之后的请求都以该 Customer 身份执行。
  • 退出或切换账号时,浏览器调用 reset(),后端调用 revokeCustomerSessions。
server/session.tsTypeScript
import { createIndianaServer } from "@tinkerlandai/indiana-sdk/server"; const indiana = createIndianaServer({  baseUrl: process.env.INDIANA_API_URL!,  apiKey: process.env.INDIANA_API_KEY!,  scope: { projectId: process.env.INDIANA_PROJECT_ID!, environment: "sandbox" },}); // Call only after your own login check succeeds.export async function issueCustomerToken(verifiedUserId: string) {  const { customer } = await indiana.getOrCreateCustomer({    externalUserId: verifiedUserId,  });  const { customerToken, expiresAt } = await indiana.createCustomerSession(customer.id);  return { customerToken, expiresAt };}
  • 在 Console 的 SDK 接入 → Allowed website origins 中登记你的网站地址。
  • 签发 Token 的 Key 需要 sessions:create,以及浏览器要调用的权限(如 entitlements:read)。
  • Token 在使用期间自动续期,最长 30 天;过期后让用户重新登录即可。

支持未登录用户

为访客生成 guestToken 并保存在 HttpOnly cookie 中,换取 Customer Token。用户登录后调用 claimGuestCustomer 绑定到其账号。

guest.tsTypeScript
import { createGuestToken, createIndianaServer } from "@tinkerlandai/indiana-sdk/server"; const indiana = createIndianaServer({  baseUrl: process.env.INDIANA_API_URL!,  apiKey: process.env.INDIANA_API_KEY!,  scope: { projectId: process.env.INDIANA_PROJECT_ID!, environment: "sandbox" },}); // 1. First visit: create the guest token once and keep it in an HttpOnly cookie.export async function startGuest(savedGuestToken?: string) {  const guestToken = savedGuestToken ?? createGuestToken();  await indiana.createGuestCustomer({ guestToken });  const session = await indiana.resumeGuestSession({ guestToken });  return { guestToken, customerToken: session.customerToken };} // 2. After your own login succeeds: bind the guest to the verified account.export async function claimGuest(input: {  guestToken: string;  verifiedUserId: string;  requestId: string;}) {  const { customer, switched } = await indiana.claimGuestCustomer({    guestToken: input.guestToken,    externalUserId: input.verifiedUserId,    requestId: input.requestId,  });  const { customerToken } = await indiana.createCustomerSession(customer.id);  return { customerToken, switched };}

相关接口

Customer、访客与会话 (10)
createCustomer, getCustomer, listCustomers, updateCustomer, createSession, renewSession, revokeSessions, createGuestCustomer, resumeGuestSession, claimGuestCustomer

相关:路径、凭据与权限见全部接口