如何为SaaS软件提供CNAME转发支持

11

我有一个Web应用程序,用户可以创建帐户并使用服务。现在我想提供自定义域名功能,其中app.customer1web.com指向myservice.com并且具有userid customer1。一旦他设置了自定义域名,对于世界来说,它看起来像我的服务正在他的机器上运行。许多像博客作者、wp.com和tumblr这样的服务都提供了这个功能。

我该如何做到这一点? 我使用Java编写我的Web应用程序。 当请求到达时,如何将域名映射到userid?

4个回答

20
我如何在请求到来时将域名映射到用户ID?
显然,你必须在某个地方存储这些信息,最可能是在数据库中。
1. 添加一个名为“domains”的数据库表,包括以下列:
- customerId - name - active(值为1或NULL) - challenge 添加(name,active)唯一键以确保一个域名只映射一次。
2. 当客户尝试添加域名时,添加一行,其中active=NULL且challenge设置为随机字符串。
向客户显示随机字符串,并请他们在网站上放置该字符串的网页或创建虚假DNS记录以验证域名所有权(这是Google Apps的做法)。
您可以通过向管理联系人发送电子邮件或以其他方式验证所有权。
3. 当客户表示已按第2步中指示的操作完成时,请验证并设置active=1,challenge=NULL。
如果域名先前对于其他客户处于活动状态,则删除那些记录或设置active=0。
4. 要求客户为其域名添加CNAME记录,并将其转发到您的域名,例如hosted.myservice.com(Google在Google Apps中使用ghs.google.com)。
5. 当请求到达时,进行:
SELECT customerId FROM domains WHERE name=:requestDomain AND active=1
更好的方法可能是自动为您的客户提供格式为<customername>.myservice.com的域名,除了自定义域名。这样可以带来两个好处:
- 不想使用自己域名的客户仍然可以自定义其登录页面,例如公司标志。 - 对于自定义域名,您可以要求您的客户将它们转发到<customername>.myservice.com而不是一个通用的hosted.myservice.com
这使您能够在多个服务器之间水平分区客户,而无需要求客户端进行任何更改。例如,您可以为客户提供选择是否将其帐户托管在欧盟或美国的选项。当他们更改时,只需传输其数据并更新<customername>.myservice.com。他们的自定义域名将自动工作。
要实现这一点,您需要为*.myservice.com设置通配符DNS记录(除非您还需要后面的功能,在这种情况下,您将不得不管理各个记录)。

我认为这是一个很好的答案。我学到了东西,谢谢你,Jaka! - Upgradingdave
1
为什么您需要验证域名所有权?如果他们可以添加CNAME,那不是足够的证明吗? - Christian Davén
@ChristianDavén 你需要CNAME验证!让我们以Tumblr为例(我相信他们有这个问题)。ABC公司即将推出,他们将使用blog.ABC.com进行发布。邪恶的XYZ公司在Tumblr上注册了CNAME blog.ABC.com,指向他们的博客,在ABC之前。没有验证,它应该指向哪个博客? - Adam Gent
这是一个很好的答案,但需要注意的是SSL可能会成为此设置的问题。 - Igor Romanov
@jaka-jančar 在完成所有这些步骤后,我们如何处理自定义域名的 SSL 证书呢? - Danyal Malik

2
您可以使用一种解决方案,即为您的应用程序设置通配符DNS记录,并让应用程序本身检查RequestURI以查看用户使用的主机名。
我知道这是一个非常模糊的答案,但是设置通配符记录,并使用单个函数检查主机名似乎是最好的选择。这样,您不必每次客户注册时都设置DNS记录,并且您有更多的时间来做其他事情...比如为您的应用程序添加新功能!

0

我不太确定我是否真正理解您想要做什么,但我会尝试为您提供可能的解决方案(至少针对您问题的Java部分)。

一种可能性是设置应用程序服务器,以便每个请求都由一个单独的Servlet(web.xml)处理。此Servlet可以了解有关请求URL(HttpServletRequest.getRequestURI)的信息并提取用户名。然后,您就知道了用户的信息,并可以将此信息用于您想要做的任何事情。

请注意,您想要做的事情涉及大量DNS内容!(至少在我理解的范围内。)


0

@jaka的回答解释得很清楚。此外,如果您正在使用ngnix作为负载均衡器,可以使用以下配置转发原始主机名。

proxy_set_header Host $host;

如果您正在使用Express(Node.js),则可以从请求头中读取主机名(CNAME)。您可以使用CNAME和用户Cookie进行授权检查。
对于证书,您可以使用*.example.com(通配符)。

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