@tmxk/iam (0.3.3)
Installation
@tmxk:registry=https://gitea.cspy.site/api/packages/shigu/npm/npm install @tmxk/iam@0.3.3"@tmxk/iam": "0.3.3"About this package
tmxk-iam
tmxk-iam 是嵌入 Node.js / Next.js 业务系统的身份与访问管理 SDK。它管理用户、外部身份、企业成员、角色、权限、数据范围、会话和审计;微信 AppSecret 与 OAuth 流程仍由独立的 tmxk-identity 负责。
设计文档:微信自助登记与管理员审核设计。
定位
- 核心是 headless SDK,业务系统可以完全自定义 UI。
- 提供稳定的业务 API,不向业务层暴露 Drizzle 或 IAM 表。
- 第一版使用 SQLite,存储接口可以继续实现 PostgreSQL 方言。
- 权限由业务系统固定定义;角色可以预设,也可以由管理员自定义。
- 角色可以绑定到系统、企业、项目或本人范围。
安装与初始化
pnpm add @tmxk/iam
import { createIam } from "@tmxk/iam";
import { createSqliteStorage } from "@tmxk/iam/sqlite";
import { createNextIam } from "@tmxk/iam/next";
export const iam = createIam({
applicationId: "lab-flow",
storage: createSqliteStorage({ filename: "./data/iam.db" }),
permissions: [
{ key: "project.read", name: "查看项目", resourceType: "project", actions: ["read"] },
{ key: "project.manage", name: "管理项目", resourceType: "project", actions: ["create", "update", "delete"] },
],
presetRoles: [
{ key: "organization_admin", name: "企业管理员", permissions: ["project.read", "project.manage"] },
{ key: "viewer", name: "查看者", permissions: ["project.read"] },
],
identity: {
issuer: process.env.TMXK_IDENTITY_ISSUER!,
providerConfigId: process.env.TMXK_IDENTITY_PROVIDER_CONFIG_ID!,
redirectUri: process.env.TMXK_IDENTITY_REDIRECT_URI!,
firstLogin: "pending",
},
});
export const nextIam = createNextIam(iam, {
stateSecret: process.env.TMXK_IAM_STATE_SECRET!,
});
应用启动时执行一次:
await iam.initialize();
微信登录
登录入口 Route Handler:
import { nextIam } from "@/lib/iam";
export async function GET(request: Request) {
const returnTo = new URL(request.url).searchParams.get("returnTo") ?? "/";
return Response.redirect(nextIam.createLoginUrl({ returnTo }));
}
回调 Route Handler:
import { nextIam } from "@/lib/iam";
export const runtime = "nodejs";
export async function GET(request: Request) {
return nextIam.handleCallback(request);
}
在 tmxk-identity 的对应 Provider 中,需要将 systemKey 配成这里的 applicationId,并将业务系统回调地址加入精确白名单。
首次登录策略:
pending:创建待审核用户,管理员确认企业和角色后启用,推荐默认值。auto-create:自动创建并启用用户,适合低风险内部应用。binding-only:只允许已经绑定的微信登录。
账号密码
await iam.passwords.set(userId, "admin", "至少十个字符的密码");
const user = await iam.passwords.authenticate(username, password);
const sessionToken = await iam.sessions.create(user.id);
账号统一按小写保存;密码使用带独立随机盐的 scrypt 哈希。连续失败 5 次后锁定 15 分钟,数据库不保存明文密码。
绑定微信
绑定入口必须先校验当前业务会话,不能接受浏览器随意指定的用户 ID:
const principal = await nextIam.requirePrincipal(request);
const url = nextIam.createLoginUrl({
mode: "bind",
userId: principal.userId,
returnTo: "/settings/account",
});
return Response.redirect(url);
回调仍复用登录回调。SDK 会拒绝把一个已经绑定的微信身份绑定给另一用户。
默认不会仅凭 unionId 自动合并用户;确认所有相关公众号属于同一微信开放平台主体后,才可以显式设置 linkByUnionId: true。
权限和数据范围
单条资源校验:
await iam.access.require({
principal,
action: "project.read",
resource: { type: "project", organizationId, projectId, ownerId },
});
列表查询先取得抽象数据范围,再由业务 Repository 编译成自身 ORM 的查询条件:
const scope = await iam.access.queryScope({ principal, action: "project.read" });
return projectRepository.list({ scope });
IAM 不拥有项目、实验、订单等业务表;它只计算当前人员有权访问哪些企业、项目或本人数据。
UI
当前包是 SDK,不强制任何管理界面。业务系统通过这些 API 实现自己的用户管理、企业管理、角色编辑、授权和微信绑定页面。后续可以增加独立的 @tmxk/iam-react 无样式组件,以及可复制的 Next.js 管理页面模板,而不让核心包绑定特定视觉样式。
安全边界
- 微信 AppSecret 只保存在
tmxk-identity。 - 浏览器只接触一次性 Code,业务系统后端完成交换。
systemKey必须与 IAM 的applicationId一致。returnTo只允许站内绝对路径,避免开放重定向。- Session 只以 SHA-256 哈希形式存库,Cookie 使用 HttpOnly、SameSite=Lax、生产环境 Secure。
- 不向业务层导出数据库连接;所有权限判断都必须在服务端完成。
Dependencies
Dependencies
| ID | Version |
|---|---|
| drizzle-orm | ^0.45.2 |
Development Dependencies
| ID | Version |
|---|---|
| @types/node | ^26.0.0 |
| typescript | ^7.0.2 |
Peer Dependencies
| ID | Version |
|---|---|
| next | >=16 |