如何在不使用子域的情况下设置多租户Rails应用程序?

问题描述 投票:2回答:1

我正在尝试创建一个带有后端的SAAS电子商务工具,该工具还允许客户在前端拥有帐户和结账。我正在努力设计这个问题,以便公司,客户所有者,员工和客户都被分散到每个公司,同时根据他们的角色进行适当的限制。

从我到目前为止所读到的,大多数rails解决方案都使用带有子域的多租户模式,例如Apartment gem来封锁帐户。但是让你的网站使用一个大的应用程序和数据库似乎更简单。例如,Basecamp最近使用Basecamp3切换到这种方法。较新的应用程序似乎是以这种方式构建的。

并且,管理员功能和客户帐户/前端商店应该完全是单独的应用程序,还是可以使用“majestic monolith”执行此操作?一个大的应用程序和数据库虽然很大,但对我来说似乎更直接。

我发现this blog post解释了如何使用Pundit做这样的事情,但我仍然无法在同一个应用程序中了解如何与帐户所有者,员工和客户合作。

以下是我的应用程序的基本需求:

用户角色

  • 帐户所有者(创建公司帐户并可以完全访问其公司的数据)
  • 员工(被邀请加入公司并且无法访问公司的某些数据,例如结算信息)
  • 客户(可以注册网站并查看产品,将其添加到购物车,但无法访问任何员工或帐户所有者功能。)
  • 所有用户(无论角色)属于公司,无法访问其他公司的数据。 (因此提供了在同一个应用程序上运行单独存储的能力,这需要将其作为SAAS应用程序运行。)
  • 帐户所有者和员工可以是CRUD产品,但不是客户。

一个很好的比喻是Shopify的管理区域和客户帐户目前如何为店主工作,但与Shopify不同,它不需要使用子域。

潜在的模型和关联

Company
has_many :users, dependent: :destroy
has_many :products, dependent: :destroy

User
belongs_to :company

Product
belongs_to :company

授权

  • 是否可以使用Pundit根据用户角色限制控制器操作,然后确保数据通过模型关联平铺?

注册流程

我对如何处理不同用户角色的范围以及“员工邀请”和“客户”注册可以适应注册流程的方式有点模糊。

这种方法有用吗?

  1. 为“帐户所有者注册”,“员工注册”,“客户注册”创建单独的控制器,然后将我的注册表单嵌入到这些视图中。 (使用Clearance进行身份验证,并希望尽可能保留,但只需根据需要进行扩充)。
  2. 帐户所有者注册:因此,如果有人通过新帐户注册控制器(使用嵌入式身份验证表单)注册,他们也会创建公司。
  3. 员工邀请:帐户所有者可以通过输入姓名和电子邮件地址来创建新的员工用户。这将创建一个角色为“Staff”的新用户(因此无法成为另一个帐户的帐户所有者)。向新“员工”用户发送一封邀请电子邮件,该电子邮件基本上是密码重置电子邮件,邀请他们通过创建密码接受邀请。
  4. 客户注册:如果有人通过“客户注册”控制器注册,他们将自动获得用户角色“客户”。在这种情况下,不确定如何设置公司ID。 (将company_id作为客户注册表单上的隐藏输入传递?)

是否有更好的方法来设计我缺少的这类应用?我是在正确的轨道上吗?我没有建立这样的经验,所以任何线索都会非常有帮助。

似乎更新的应用程序遵循这种多租户模式而不是子域。

ruby-on-rails ruby authorization multi-tenant pundit
1个回答
2
投票

你打开simple e-commerce site,但你问的问题表明你正在寻找一些更复杂的东西:)你走在正确的轨道上。

acts_as_tenant gem值得一看。我们现在使用它,它有助于确保您的查询都适当的范围。

如果你需要做角色,我也会看看&评估rolify(但不要排除你用户的布尔标志)。

我不排除设计,但清除很受欢迎。

使用子域可能是未实现的工作,具体取决于工作量,除非您需要实际使用子域以实现虚荣(my.example.com vs example.com/my),否则您可以在没有它的情况下进行多租户。

如果他们的访问变化很大,我会考虑不同角色的单独控制器和命名空间;你也可以使用Pundit将它们组合成单个控制器(但这可能很笨重)。你仍然想要使用Pundit,但是,Pundit可以做一些事情,比如用户应该看到的记录范围。

你走在正确的轨道上并提出正确的问题,但所有这些问题的答案将取决于其他问题(你现在甚至无法回答)。

我有一个项目,我正在做你所注意到的事情(专家限制数据,act_as_tenant到筒仓事物),但随着它的发展,某些模式出现,导致我走上了不同的道路。命名空间管理员,而不是在同一控制器内进行管理员检查;因为如果你重写一个API,你最终会尝试让同一个端点做不同的事情,并且在命名空间后面分离2个端点并记录我认为的实际行为要清楚得多。

© www.soinside.com 2019 - 2024. All rights reserved.