Better-Auth 多组织功能开发指南
基于现有代码的 Better-Auth 多组织功能实现教程,包含配置、使用和数据存储的完整指南
🏢 Better-Auth 多组织功能开发指南
目标: 学习如何使用 Better-Auth 构建多组织(多租户)应用,实现组织管理、成员邀请和权限控制
📋 功能概览
什么是多组织功能?
多组织功能允许一个应用支持多个独立的组织(团队、公司、社区等),每个组织有自己的成员、数据和权限体系。这是 dashboard 应用的核心功能之一。
文档
请参考以下文档来获得对 Better-Auth 多组织功能的详细说明: https://www.better-auth.com/docs/plugins/organization
核心特性
- 组织管理: 创建、编辑、删除组织
- 成员管理: 邀请、移除、角色管理
- 权限控制: 基于组织和角色的访问控制
- 数据隔离: 每个组织的数据相互独立
- 邀请系统: 邮件邀请和接受流程
🎯 React Hooks 使用
Better-Auth 提供了便捷的 React Hooks:
1. 基础 Hooks
import { useSession } from "@/lib/auth/client";
function OrganizationComponent() {
const { data: session } = useSession();
// 获取当前活跃组织ID
const activeOrganizationId = session?.activeOrganizationId;
// 获取用户所属的所有组织
const userOrganizations = session?.user.organizations || [];
return (
<div>
<h2>当前组织: {activeOrganizationId}</h2>
<h3>我的组织列表:</h3>
{userOrganizations.map(org => (
<div key={org.id}>{org.name}</div>
))}
</div>
);
}
2. 组织切换
// 切换活跃组织
const switchOrganization = async (organizationId: string) => {
await authClient.organization.setActiveOrganization({
organizationId,
});
// 页面会自动刷新以反映新的组织上下文
window.location.reload();
};
3. 权限检查
// src/lib/auth/lib/helper.ts
import type { ActiveOrganization } from "../auth";
export function isOrganizationAdmin(
organization?: ActiveOrganization | null,
user?: { id: string; role?: string | null } | null,
) {
const userOrganizationRole = organization?.members.find(
(member) => member.userId === user?.id,
)?.role;
return (
["owner", "admin"].includes(userOrganizationRole ?? "") ||
user?.role === "admin" // 全局管理员
);
}
// 使用示例
function AdminPanel() {
const { data: session } = useSession();
const { data: organization } = useOrganization();
const isAdmin = isOrganizationAdmin(organization, session?.user);
if (!isAdmin) {
return <div>无权限访问</div>;
}
return <div>管理员面板</div>;
}
📊 数据存储和隔离
1. 组织数据关联
为了实现数据隔离,需要在业务模型中添加组织关联:
// 示例:活动模型
model Event {
id String @id @default(cuid())
title String
description String
organizationId String // 关联到组织
createdById String // 创建者
organization Organization @relation(fields: [organizationId], references: [id])
createdBy User @relation(fields: [createdById], references: [id])
}
// 示例:项目模型
model Project {
id String @id @default(cuid())
name String
organizationId String // 关联到组织
ownerId String // 项目负责人
organization Organization @relation(fields: [organizationId], references: [id])
owner User @relation(fields: [ownerId], references: [id])
}
2. 数据查询过滤
在所有数据查询中添加组织过滤:
// 获取当前组织的活动列表
export async function getOrganizationEvents(organizationId: string) {
return db.event.findMany({
where: {
organizationId, // 只返回当前组织的数据
},
include: {
createdBy: true,
},
});
}
// 创建组织数据
export async function createEvent(data: {
title: string;
description: string;
organizationId: string;
createdById: string;
}) {
return db.event.create({
data: {
...data,
organizationId: data.organizationId, // 确保数据属于正确的组织
},
});
}
🚀 实际应用场景
1. 社区分部功能
在我们的项目中,可以将组织功能用于社区分部:
// 创建社区分部
const createChapter = async (chapterName: string) => {
return authClient.organization.create({
name: `${chapterName}`,
slug: chapterName.toLowerCase(),
});
};
// 活动关联到社区分部
model Event {
// ... 其他字段
organizationId String? // 关联到社区分部
organization Organization? @relation(fields: [organizationId], references: [id])
}
2. 团队协作
// 项目团队管理
const createProjectTeam = async (projectName: string) => {
return authClient.organization.create({
name: `${projectName}团队`,
slug: `${projectName}-team`,
});
};
📝 最佳实践
1. 数据安全
- 始终在查询中包含组织过滤
- 使用中间件验证组织访问权限
- 定期审计跨组织数据访问
2. 用户体验
- 提供清晰的组织切换界面
- 在邀请流程中给出明确的反馈
- 支持批量操作以提高效率
3. 性能优化
- 使用数据库索引优化组织相关查询
- 缓存组织信息减少重复查询
- 分页处理大型组织的成员列表
4. 错误处理
- 优雅处理邀请过期和无效邀请
- 提供清晰的权限错误提示
- 记录组织操作日志便于调试
🎯 下一步
- 实践练习: 在开发环境中创建组织和邀请成员
- 功能扩展: 根据业务需求添加自定义组织功能
- 性能优化: 监控和优化组织相关查询性能
- 安全审计: 定期检查组织权限和数据隔离
通过本教程,你应该能够理解和使用 Better-Auth 的多组织功能来构建强大的多租户应用。记住,多组织功能的核心是数据隔离和权限控制,确保每个组织的数据安全是最重要的。