14

我正在创建一个saas应用程序。用户有自己的网址,例如user .mysaasapp.com

为了让用户拥有自己的 url,我使用了 mod rewrite。http://mysaasapp.com/?user=user类似的东西user.mysaasapp.com(这工作得很好)

现在,我想让用户灵活地屏蔽他们的网址。这意味着用户可以将他们的子域 (saas.theirdomain.com) 定向到 user.mysaasapp.com。我该怎么做。

我阅读了很多关于此的文章(cname),但仍然没有明确的解决方案。我想知道像 wordpress/google 这样的大公司是如何做到的。

例如http://www.tumblr.com/docs/en/custom_domains

例如http://developer.uservoice.com/docs/site/domain-aliasing/

我意识到公司会采取这个过程:

  1. 让用户添加 cname
  2. 让用户在 saas 应用程序中输入他们的域(可能在自定义域下)

我需要什么才能让这个工作?谢谢!

4

5 回答 5

4

如果我是对的,您可以在其中使用通配符ServerAlias并使用 mod_rewrite 您可以将其重写为正确的文件,这样您的虚拟主机就会像

<VirtualHost *:80>
    ServerName mysaasapp.com
    ServerAlias *.mysaasapp.com
    DocumentRoot /var/www/user
</VirtualHost>

你的 CNAME 就像

*.mysaasapp.com IN CNAME mysaasapp.com

我希望这有帮助

编辑:

将虚拟主机更改为

<VirtualHost *:80>
    ServerName mysaasapp.com
    ServerAlias *.mysaasapp.com
    DocumentRoot [STANDARDFOLDER]
</VirtualHost>

并替换[STANDARDFOLDER]DocumentRootmysaasapp.com 的

并在您index.php的顶部:

// Array with all the subdomains who doesn't belong to users
$_notUsers = array("www");
// No code without a Boom,
$_domainParts = explode('.',$_SERVER[HTTP_HOST],-2);
// Check if subdomain is legit
if(!in_array($_domainParts[0],$_notUsers) && !empty($_domainParts)){
    // get the real subdomain structure
    $_sub = str_replace('.mysaasapp.com','',$_SERVER['HTTP_HOST']);
    // Don't look at this it's horrible :'( but this makes it think that there is 
    // something in user 
    $_GET['user'] = $_sub;
    // I dont know where you want it in the question its index.php and in comment its 
    // user.php so change this as you want it
    include 'user.php';
    // Exit so we dont have an user page and homepage together but only when
    // using user.php comment this out when using index.php
    exit;
// end
}

这是一个非常肮脏的解决方案,我希望它现在对你有用

更新:

起初我不知道你也想从自定义域重定向,

然后他们必须将 CNAME 添加到他们的 DNS 服务器/管理器

theirdomain.com IN CNAME thierusername.mysaasapp.com

如果您的 DNS 记录是这样的,那么所有子域都将转到您的 apache,它是否应该使用我给您的代码和 Vhost

更新 2:

lanzz 刚刚指出了一些我忘记的东西(facepalm),我正在检查 HOST 标头这是没有意义的,因为它会有,customdomain.com所以你需要向你的用户询问他们的域(如果你没有共享 IP,让他们用 CNAME 指向,如果你没有共享 IP,您可以让他们使用 A 记录指向您的 IP)并从 HTTP_HOST 查找域,然后在您的数据库中搜索它应该可以工作!

一点点编辑的代码:

//first look if you're on your own domain,
// also again an Array with all the subdomains who doesn't belong to users
$_notUsers = array("www");
//lets explode the domain 
$_domainParts = explode(".",$_SERVER["HTTP_HOST"]);
//get length of $_domainParts
$_domainPartsLength = count($_domainParts);
//get last two parts (little bit ugly but there are uglier ways)
$_currentDomain = $_domainParts[$_domainPartsLength-1] . "." . $_domainParts[$_domainPartsLength-2];
//time to check if it's yours and if it's legit
if($_currentDomain == "mysaasapp.com"){
    if(!in_array($_domainParts[0],$_notUsers) && !empty($_domainParts)){
        // get the real subdomain structure
        $_sub = str_replace('.mysaasapp.com','',$_SERVER['HTTP_HOST']);
        // Don't look at this it's horrible :'( but this makes it think that there is 
        // something in user 
        $_GET['user'] = $_sub;
        // I dont know where you want it in the question its index.php and in comment 
        // its user.php so change this as you want it
        include 'user.php';
        // Exit so we dont have an user page and homepage together but only when
        // using user.php comment this out when using index.php
        exit;
    }
    // here is your standard index (sorry for the odd placing)
}else{
    //now here are we gonna play with the custom domain
    // this function should return the username if the hostname is found in the
    // database other wise it should return false
    $_user = userGetByDomain($_SERVER["HTTP_HOST"]);
    if($_user === false){
        // tell the browser its not legit
        header("Status: 404 Not Found");
        //show your 404 page
        include '404.php';
        // and die
        exit;
    }
    // now we know everything is okay we are gonna do the same thing as above
    $_GET['user'] = $_user;
    // I dont know where you want it in the question its index.php and in comment 
    // its user.php so change this as you want it
    include 'user.php';
    // Exit so we dont have an user page and homepage together but only when
    // using user.php comment this out when using index.php
    exit;
}
于 2012-08-06T11:58:23.297 回答
2

由于您要处理站点上抛出的任何主机名,因此您需要将站点放在主虚拟主机中(配置中首先出现的主机)。主虚拟主机将处理没有为其主机名定义特定虚拟主机的主机名的所有请求。

在您的代码中,您应该检查$_SERVER['HTTP_HOST']并从中确定相关用户。您将需要处理四种不同的情况:

  1. 该请求针对您的主域(或www.yourmaindomain),在这种情况下,您没有相关用户
  2. 该请求是针对您主域上的子域(例如foouser.yourmaindomain),那么您知道该请求是针对foouser
  3. 该请求不是针对上述任何一项,但您已将用户配置为使用该主机名。您将需要在代码中维护这些域到用户的分配,这超出了本问题的范围。
  4. 该请求不是针对上述任何一项;有人错误地将主机名指向了您的 IP,或者指向了错误的主机名,或者该主机名尚未分配给用户,或者有人出于任何原因在您的 IP 上访问了错误的主机名。对于这种情况,您将需要显示某种未找到的页面。

@EaterOfCorpses 的解决方案似乎假设您将能够确定用户记录指向的主机名;CNAME这很少是真的,并且在很大程度上取决于用户的浏览器(即浏览器需要包含Host: <CNAME target>而不是包含Host: <original hostname>在 HTTP 请求中,但浏览器会提供 URL 中使用的原始主机名,这仍然是用户的自定义域,而不是username.yourdomain指向根据CNAME记录)。

于 2012-11-02T15:44:55.960 回答
2

在您的客户端创建 cname 后,您需要让 Apache 知道以侦听它。

因此,如果您有一个非常简单的虚拟主机设置,就像这样

<VirtualHost *:80>
    ServerName user.mysaasapp.com
    DocumentRoot /var/www/user
</VirtualHost>

你客户的 cname 是这样的

customdomain.com        IN      CNAME  user.mysaasapp.com

您需要将 customdomain.com 添加到您的虚拟主机条目中,因此它变为

<VirtualHost *:80>
    ServerName user.mysaasapp.com
    ServerAlias customdomain.com
    DocumentRoot /var/www/user
</VirtualHost>

我在这里做了一些假设,但这就是我过去的做法,当然不包括任何拼写错误。

于 2012-07-31T15:02:57.963 回答
0

假设您使用的是 Apache httpd(基于 mod_rewrite 的提及),您将使用以下 httpd 配置(来自http://httpd.apache.org/docs/2.2/vhosts/mass.html#simple):

httpd.conf 的简单动态虚拟主机示例

# get the server name from the Host: header
UseCanonicalName Off

# this log format can be split per-virtual-host based on the first field
LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon
CustomLog logs/access_log vcommon

# include the server name in the filenames used to satisfy requests
VirtualDocumentRoot /www/hosts/%0/docs
VirtualScriptAlias /www/hosts/%0/cgi-bin

然后,您将需要您的“saas 应用程序”将其 CNAME“saas.theirdomain.com”链接(以符号方式或其他方式)作为如下目录:“/www/hosts/saas.theirdomain.com/docs”基于示例以上。

例如

ln -s /www/mysaasapp/user /www/hosts/saas.theirdomain.com

/www/mysaasapp/user 是您的 saas 应用程序所在的位置。

于 2012-08-06T19:20:18.443 回答
0

如果您的用户为您的服务使用默认端口,那么您无需担心任何事情。只需告诉您的用户更改 DNS 管理器中的 CNAME(别名)和 A(主机)设置。

@ --> 将指向 DOMAIN_NAME (如果他们想将 theirdomain.com 屏蔽到您的服务中)。

saas --> 将指向 user.mysaasapp.com(如果他们想将 saas.theirdomain.com 屏蔽为您的服务)。

如果您让他们使用特定端口使用您的特定服务,那么您可以将其添加到您的 VirtualHost 设置中

<VirtualHost *:[[PORT_NUMBER]]>    // set to 80 if no special ports required.
ServerName mysaasapp.com
ServerAlias user.mysaasapp.com    // Change [[user]] to custom user's alias.
DocumentRoot USER_FOLDER 
</VirtualHost>

我希望这能解决你的问题。

于 2012-11-05T09:27:50.483 回答