onestack-auth
v0.2.3
Published
TypeScript SDK for the OneStack auth service: OIDC (Authorization Code + PKCE) client core and managed-profile API. Framework- and runtime-agnostic (Node 22+, Workers, Deno, Bun).
Readme
onestack-auth
OneStack 身份服务的 TypeScript 客户端 SDK:OIDC(Authorization Code + PKCE)协议核心 + 托管资料 API 客户端。
设计边界(重要)
SDK 主入口只做协议;客户端配置管理放在独立的 onestack-auth/admin 子路径和
onestack-auth CLI,不进入产品登录运行时:
- ✅ 发现文档(带缓存)、授权 URL + PKCE、token 交换、ID token 验签(JWKS + kid 轮换)、跨站登出/结束会话 URL、健康探测、托管资料 API
- ❌ 不碰 cookie、session、用户映射、数据库——这些语义每个产品不同,留在产品侧
运行时无关:纯 ESM + d.ts,只依赖 jose,只用 Web 标准 API(fetch / crypto.subtle),在 Node 22+、Cloudflare Workers、Deno、Bun 上行为一致。所有出站请求均可传入 AbortSignal 控制超时;所有失败归一为 OneStackAuthError(含服务端错误码与 requestId)。
安装
npm install onestack-auth后端 RP 模式(推荐)
产品后端持有 client_secret,官网/前端只做跳转与回跳页,token 不落浏览器。
import {
createAuthClient,
OneStackAuthError,
} from "onestack-auth";
const auth = createAuthClient({
issuer: "https://accounts.example.com/api/auth",
clientId: process.env.ACCOUNT_CLIENT_ID!, // 注册产品时获得
clientSecret: process.env.ACCOUNT_CLIENT_SECRET!,
audience: "https://product.example.com", // 本产品源(token audience)
});
// 1) 登录入口:跳转授权页(state/nonce/PKCE 已生成)
app.get("/login", async (req, reply) => {
const transaction = await auth.authorizationTransaction({
callbackUrl: "https://product.example.com/auth/callback",
scope: "identity:migrate", // 按需追加能力 scope
});
// ⚠️ transaction.state/nonce/codeVerifier 由产品自行保存并与回调核对
// (签名 cookie / 临时存储均可——这是产品侧职责)
return reply.redirect(transaction.authorizationUrl);
});
// 2) 回调:换 token 并验签,得到稳定身份 claims
const result = await auth.exchangeCode({
code,
codeVerifier,
callbackUrl: "https://product.example.com/auth/callback",
nonce,
});
// result.claims: StableAccountClaims(sub 唯一键、头像、联系方式…)
// 之后用产品自己的 session 机制记住 result.claims.sub
// 3) 跨站登出:顶层 GET 跳转,让账号会话一并失效
reply.redirect(productSignOutUrl(auth.config, "https://product.example.com/"));托管资料 API(需 profile:manage 能力)
import { getManagedAccountProfile } from "onestack-auth/profile";
const profile = await getManagedAccountProfile(auth.config, accountUserId);产品自助更新邮件品牌
已注册的机密客户端可以用自己的 client secret 更新名称、登录重启路径和邮件品牌, 不需要 OneStack 源码、Cloudflare 凭据或数据库权限:
ONESTACK_ACCOUNTS_URL=https://accounts.example.com \
ONESTACK_CLIENT_SECRET="$ACCOUNT_CLIENT_SECRET" \
npx onestack-auth client branding sync --file onestack.branding.json服务端只允许修改展示元数据;redirect URI、scope、client secret 等安全配置不在
这个接口的权限范围内。配置格式见仓库
examples/oidc-client-branding.json。
非 TypeScript 产品
SDK 只是提速器:服务端点是标准 OIDC(发现文档 /.well-known/openid-configuration、Authorization Code + PKCE、JWKS),任何语言用对应 OIDC 库(Python authlib、Go go-oidc…)或裸 HTTP 即可接入。见仓库 docs/auth-integration.md。
错误处理
try {
await auth.exchangeCode({ ... });
} catch (error) {
if (error instanceof OneStackAuthError) {
error.code; // 服务端错误码(AUTH_RATE_LIMITED…)或 AUTH_HTTP_ERROR / AUTH_NETWORK_ERROR / AUTH_TIMEOUT
error.requestId; // 服务端请求号,便于排查
}
}