客户与会话
创建与更新 Customer,签发 Customer Token,处理访客与登录后认领。
API v1更新于
创建或查找 Customer
用你系统里已验证的用户 ID 作为 externalUserId。同一个 ID 再次调用会返回同一个 Customer(created: false),已有资料不会被覆盖。
1import { createIndianaServer } from "@tinkerlandai/indiana-sdk/server";2 3const indiana = createIndianaServer({4 baseUrl: process.env.INDIANA_API_URL!,5 apiKey: process.env.INDIANA_API_KEY!,6 scope: { projectId: process.env.INDIANA_PROJECT_ID!, environment: "sandbox" },7});8 9async function main() {10 const { customer, created } = await indiana.getOrCreateCustomer({11 externalUserId: "user-42",12 });13 console.log(customer.id, created);14}15 16main().catch((error) => {17 console.error(error);18 process.exitCode = 1;19});
更新 Customer
只发送要修改的字段。每次更新生成一个 requestId 并保存;重试时使用同一个值,不会重复修改。
1import { createIndianaServer } from "@tinkerlandai/indiana-sdk/server";2 3const indiana = createIndianaServer({4 baseUrl: process.env.INDIANA_API_URL!,5 apiKey: process.env.INDIANA_API_KEY!,6 scope: { projectId: process.env.INDIANA_PROJECT_ID!, environment: "sandbox" },7});8 9export async function syncProfile(input: {10 verifiedUserId: string;11 requestId: string; // persisted before the first attempt12 plan: string;13}) {14 const { customer, changed } = await indiana.updateCustomer({15 lookup: { type: "externalUserId", value: input.verifiedUserId },16 requestId: input.requestId,17 patch: {18 attributes: { plan: input.plan },19 tagChanges: { add: ["beta"], remove: [] },20 },21 });22 return { customerId: customer.id, changed };23}
让浏览器直接调用
- 后端验证用户登录后,调用
createCustomerSession 签发 Customer Token。 - 浏览器调用
identify(token),之后的请求都以该 Customer 身份执行。 - 退出或切换账号时,浏览器调用
reset(),后端调用 revokeCustomerSessions。
server/session.tsTypeScript 1import { createIndianaServer } from "@tinkerlandai/indiana-sdk/server";2 3const indiana = createIndianaServer({4 baseUrl: process.env.INDIANA_API_URL!,5 apiKey: process.env.INDIANA_API_KEY!,6 scope: { projectId: process.env.INDIANA_PROJECT_ID!, environment: "sandbox" },7});8 9// Call only after your own login check succeeds.10export async function issueCustomerToken(verifiedUserId: string) {11 const { customer } = await indiana.getOrCreateCustomer({12 externalUserId: verifiedUserId,13 });14 const { customerToken, expiresAt } = await indiana.createCustomerSession(customer.id);15 return { customerToken, expiresAt };16}
- 在 Console 的 SDK 接入 → Allowed website origins 中登记你的网站地址。
- 签发 Token 的 Key 需要
sessions:create,以及浏览器要调用的权限(如 entitlements:read)。 - Token 在使用期间自动续期,最长 30 天;过期后让用户重新登录即可。
支持未登录用户
为访客生成 guestToken 并保存在 HttpOnly cookie 中,换取 Customer Token。用户登录后调用 claimGuestCustomer 绑定到其账号。
1import { createGuestToken, createIndianaServer } from "@tinkerlandai/indiana-sdk/server";2 3const indiana = createIndianaServer({4 baseUrl: process.env.INDIANA_API_URL!,5 apiKey: process.env.INDIANA_API_KEY!,6 scope: { projectId: process.env.INDIANA_PROJECT_ID!, environment: "sandbox" },7});8 9// 1. First visit: create the guest token once and keep it in an HttpOnly cookie.10export async function startGuest(savedGuestToken?: string) {11 const guestToken = savedGuestToken ?? createGuestToken();12 await indiana.createGuestCustomer({ guestToken });13 const session = await indiana.resumeGuestSession({ guestToken });14 return { guestToken, customerToken: session.customerToken };15}16 17// 2. After your own login succeeds: bind the guest to the verified account.18export async function claimGuest(input: {19 guestToken: string;20 verifiedUserId: string;21 requestId: string;22}) {23 const { customer, switched } = await indiana.claimGuestCustomer({24 guestToken: input.guestToken,25 externalUserId: input.verifiedUserId,26 requestId: input.requestId,27 });28 const { customerToken } = await indiana.createCustomerSession(customer.id);29 return { customerToken, switched };30}
相关接口
- Customer、访客与会话 (10)
createCustomer, getCustomer, listCustomers, updateCustomer, createSession, renewSession, revokeSessions, createGuestCustomer, resumeGuestSession, claimGuestCustomer
相关:路径、凭据与权限见全部接口