为什么要在多租户Web应用程序中使用子域来指定租户?

55

问题

  1. 为什么有些多租户Web应用程序使用子域来指定租户,而有些则不使用?
  2. 这是否涉及技术、隐私或安全原因?
  3. 这是否取决于用于开发Web应用程序的语言或框架?
  4. 这只是样式或开发人员选择的问题吗?

使用子域指定租户的示例Web应用程序

未使用子域指定租户的示例Web应用程序


5
建议你从一开始就设计应用程序,不要使用子域名,并将此功能作为最后一层构建。如果始终整合子域名,将来更改会变得非常不灵活。(来源:经验) - cjm2671
3
你好,如果可以避免使用子域名,请这么做!我们被迫使用自定义域名(不仅仅是子域名)用于我们的应用程序,因为我们的产品是一个完整的白标解决方案,通常需要我们的客户在他们的主机文件中设置自定义域名并指向我们的系统,并将其包含在系统设置中。不用说,这是一个漫长的过程,因为我们的许多客户也是经销商,需要做同样的事情。我真的认为我们无法避免这种情况,但如果你能的话,请尝试避免使用自定义域名 :) - Anup Marwadi
2个回答

41

在HTTP级别上确定租户的几种方法:

  • 域名 - 租户由整个Host头确定
  • 子域名 - Host头的子域名部分
  • 基于路径 - 路径段,通常是以前缀host.com/tenantId/...的形式
  • 基于cookie - cookie值包含租户ID(好的框架会进行加密!)
  • 基于用户 - 用户会话或服务器上的某些数据记录

这里是你问题的答案:

  1. 如果您希望为用户提供完全隔离的租户感知,则(子)域名多租户是不错的选择。客户可能需要定制欢迎和登录页面、单独的用户库等。另一方面,基于路径的多租户适用于不固定在单一租户命名空间的用户。它主要被社交网络如Facebook、GitHub等使用。

  2. (子)域名可以为您提供更好的隔离和安全控制,用于cookie、跨来源资源共享(CORS)。它使跨租户CSRF或XSS变得更加困难。此外,如果您对DNS或负载平衡器有控制权,可以将租户分配给不同的IP(考虑地理路由)或不同版本的应用程序(例如测试版租户)。您可以为最重要的租户分配一个单独的应用程序实例或服务器。这样,您就可以获得一种廉价的工具来控制单点故障和所有鸡蛋放在一个篮子里的风险。

  3. 任何允许您访问HTTP头文件(Host)的Web框架都支持子域名。任何严肃的MVC Web框架都应该直接或通过插件将子域名作为操作参数提供给您。

  4. 这绝对是一种设计选择。如果您想知道最好的方法,请考虑要为您的租户提供什么级别的隔离。如果您决定了,但发现这种方法不正确,则可以通过HTTP 301重定向的帮助迁移到另一个级别。


嗨@gertas,我有一个应用程序,用户可以创建自己的网站,我想允许他们编辑所选择模板的HTML和CSS,而不影响我的应用程序的安全性,你认为多租户是一个好的解决方案吗?谢谢! - medBouzid
你必须实现多租户,每个用户都有自己的空间。我建议使用子域名或域名级别,并加上适当的CORS头来防止XSS攻击。但是,如果你有非常好的HTML/CSS清洁器或者做了适当的审核处理,那么你可以尝试基于路径的多租户,例如 ebay 或者旧版的myspace。但至少要将管理员模块放在单独的域名下,并且不要直接在页面渲染这些HTML内容,可以在管理员模块中使用iframe。 - gertas
我做了一些研究,发现有(独立数据库)、(共享数据库,独立模式)、(共享数据库,共享模式)等不同的方法。由于我使用的是Rails框架,有一个叫做“apartment”的gem可以使用共享数据库,独立模式的方法。但是像Heroku这样的托管平台建议不要使用这种方法,因为这种方法已经导致了许多操作问题,并且“即使50个也会严重影响性能”。请问您对此有何经验?“子域名”能否解决这个问题? - medBouzid
3
你提到了多租户隔离的不同层次 - 数据库。我使用单个数据库模式,每个表中添加了tenant_id列来实现。 - gertas
我也在寻找类似的概念来实现一个项目,在这个项目中我需要决定使用单域名还是多子域名,为单一代码库,每个账户有多个数据库。计划使用负载均衡器,那么什么是最好的选择,单域名-多租户还是多子域名-多租户? - Pragnesh Karia

4
  1. 请见下方。
  2. Cookies可能是最明显的,其次是您可以更改子域名的DNS设置,但无法更改路径的DNS设置。
  3. 不可以。
  4. 部分地是,详见上文。

1
这个答案太简洁了,我几乎无法理解。 - lunohodov
需要在OP的问题旁边阅读(有序列表)。简洁通常非常好(尤其是在代码中)。我要说的是,在2011年,在(早期的)asp.net MVC中,这并不容易;我做到了,但并不容易。无论如何,今天我认为这是一个非常有信息量的答案。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接