hello,大家好,我是Ray,这期视频我来分享如何实现自定义域名是一个 SaaS 类应用很普遍的需求,通常 SaaS 类应用它会有一个主域名,例如这个 example dot com,然后它会给每个客户分配一个二级域名,像这个 customer 点 disable 到name,然后客户可以指定一个自定义域名,这样的话为客户提供的服务就可以更品牌化和个性化一点。
那么这个功能要怎么实现呢?我打算分三部分来讲,包括了应用层、 DNS 设置,还有SSL 的证书。好,那么首先是应用层,我们首先要知道每个 HTTP 请求它会带有一个 host 头, host 里面的信息就是当前请求它所访问的主机域名,我们就可以利用这个头来区分不同的子站。
首先你要在你的模型上里面添加一些域名相关的字段,像 subdomain 还有 customer domain。我另外加了两个字段,用来标记这个 customer domain 是否已经就绪。另外我给这两个字段加上了唯一的索引。在接下来是路由的部分,我主要是区分了两种情况,一个是主站的域名,主站域名就会是你的网站首页或者是注册页面等等。然后如果它的 request 或者不是你的主站域名,那么它可能是一个二级域名,也可能是一个自定义域名,这样就进入 set 模块里面来处理。
那么在 set 模块里面我会有一个 base Controller,这个 base Controller 就会有一个 before action 用来设置当前的set,这个 set 关键就是这个 require host 一块,或者就是拿到 HTV 头里面的 host 信息,然后用它来匹配你的子域名的正则,如果它匹配的上的话,那么就是用匹配到的二级域名部分来查询你的子站,如果它匹配不上,说明它是一个自定义域名,那么就从已经配置了自定义域名的站点里面查询这个自定义域名。
如果这两个查询都找不到内容的话,就说明这个域名是一个无效的域名,我就重定向到网站的首页,那么再来看一个 post Controller 的一地址,这个 Controller 就继承了刚刚那个 base Controller,然后里面在查询 pose 的时候就用这个已经准备好了的 side 的那个实例变量来查询它的pose。这里要特别小心的就是如果你没有把查询限定在子站范围内,就有可能造成数据泄露,这样的话你的客户就会跟你说拜拜了。
这里你可以找一些关于 race 多租户的一些句来帮你管理这些查询,不过因为我本身没有用到,所以我这里就不推荐了。在获取这块或者的时候,有一种情况是你获取一个你获取的或者是空的,或者获取一个错误的host,那么这就有可能是你的 http Server 没有正确的把 request host 传到 APP 应用里面。例如 Nginx,就是需要以上一些配置把这个 HTTP 的头透传到后方的,如果你是用卡里的话,它已经默认透传了的,就不需要额外设置。
那么接下来是 DNS 的部分, DNS 要设置的内容我已经列在这个表格里面了。首先是主站域名,应该有一个 A 记录,指向你的 Server IP,然后是二级域名,你应该设置一个泛域名解析,也是 A 记录,然后指向你的 Server IP。
第三个是自定义域名,这个是在用户侧的 DNS 设置的,它需要把它想要用的二级域名 cname 到你给它分配的二级域名上,这里用 cname 的意思就是说让 DNS 查询这个域名的时候获得这个 c name 的值,然后再查一遍这个 cname 的值,然后获得真实的IP,这样的好处,那就是你如果更改了你的 Server IP,你只要更改你自己 DNS 上的这两个记录就行了。
客户那一侧的 DNS 就不需要修改,因为它是动态。这里要提醒的就是,在下一步申请 SSL 证书之前,你应该要校验你用户的点时设置有没有正确,不然你申请 SSL 证书的时候, DNS 设置不正确,你就会把它浪费 SSL 证书的那个额度。接下来是 SSL 证书的部分。要处理 SSL 证书,首先要搞清楚的是你要在哪一个部分处理证书。如果你是这种典型的部署架构,例如一个 Nginx 或者 Caddy Server,然后在内网里面指向你的 APP server 的话,那么你就需要在你的 HTTP Server 这里处理 SSL 证书,那么 HTTP Server 我就强烈推荐用卡底的,因为它是一个自动处理 HTTPS 的一个Server。
那么关于 Caddy,我之前写了一篇博客,关于怎么用卡底来管理 HTTPS 证书的,大家可以去浏览一遍,这里就不重复了。嗯,这里就可以看一下最终的结果,我大概讲一下。首先要关注的是这个问题,on_demand_tls 的配置,如果在这里设置了 tls on demand,它的意思就是说无论哪个请求进来,只要是 https 的请求,它就自动被它申请一个证书,这样方便是方便,但是网络上有很多恶意的爬虫,它可能会带一些莫名其妙的 host,如果你每一个请求都帮他申请一个证书,会很快会让你的那个证书额度爆掉,然后就干扰你的正常证书申请。
所以 caddy 它就提供了一个配置,在按需申请 TLS 证书之前,先去请求你的后端服务检查一下这个域名是不是允许使用的,它返回一个 200 OK 的情况下才会继续为他申请证书,这样就避免了一些恶意请求把你的证书额度耗完。另一种情况就是在你的 HTTP Server 之前还有一层 CDN 的 Proxy,例如如果你用了 cloudflare 就的话就是这种情况。那么这种情况浏览器建立 https 请求实际上是跟 CDN 的节点建立请求,那么证书就应该在 cdn 节点这一块进行处理,那么你用到的 cdn 不同,它的处理方法是不一样的,这里我也不展开描述。
例如像 cloudflare 就有一个专门为 SaaS 类应用提供的一个文档页面,里面就包含了怎么申请证书,它是通过 API 来操作的,如果你部署在 fly io 的话, fly io 也有一个专门的文档页面来讲述怎么申请 SSL 证书。这里要提醒的就是你要注意你在证书签发限制,通常来说证书先发会有频率限制,费用还有总数上限的要求的,您需要在用户侧做一些限制,防止一些恶意的请求或者重复的请求,把你的那个额度耗完。好,接下来我们总结一下,首先是在应用层应该要根据 http 的头来区分子站还有DNS,应该要设置主站域名,子站的泛域名,还有用户侧的自定义域名。第三就是根据你的部署方案来选择签发 SSL 证书的方案。以上就是实现自定义域名功能的一些主要的要点,可能有一些细节没有在视频里面说明,大家可以在评论区再提出,我们再来讨论。好,这期视频就是这样,我们下期视频再见。拜拜。