如何blogger / wordpress / tumlr允许用户掩盖网址

时间:2012-07-28 18:33:03

标签: php .htaccess mod-rewrite cross-domain cname

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

为了让用户拥有自己的网址,我使用mod重写。像http://mysaasapp.com/?user=useruser.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应用程序中输入他们的域名(可能在自定义域下)
  3. 我需要什么才能使这个工作?谢谢!

5 个答案:

答案 0 :(得分: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]替换为myscaasapp.com的DocumentRoot

在您的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应该使用代码和我给你的Vhosts

更新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;
}

答案 1 :(得分: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>

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

答案 2 :(得分:2)

由于您要处理站点中引发的任何主机名,因此您需要将站点放在主虚拟主机(the one appearing first in your configuration)中。主虚拟主机将处理没有为其主机名定义特定虚拟主机的主机名的所有请求。

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

  1. 请求适用于您的主域(或www.yourmaindomain),在这种情况下您没有相关用户
  2. 请求适用于您主域的子域名(例如foouser.yourmaindomain),然后您知道该请求适用于foouser
  3. 请求不适用于上述任何一项,但您已将用户配置为使用该主机名。您需要在代码中维护这些域到用户的分配,这超出了本问题的范围。
  4. 请求不适用于上述情况;有人错误地指出了您的IP主机名,或者指出了错误的主机名,或者主机名尚未分配给用户,或者有人因为任何原因只是在您的IP上访问了错误的主机名。在这种情况下,您需要显示某种未找到的页面。
  5. @EaterOfCorpses'解决方案似乎假设您将能够确定用户的CNAME记录所指向的主机名;这很少是真的,并且在很大程度上取决于用户的浏览器(即浏览器需要在HTTP请求中包含Host: <CNAME target>而不是Host: <original hostname>,但浏览器会提供URL中使用的原始主机名,这将是仍然是用户的自定义域,而不是username.yourdomain记录指向的CNAME

答案 3 :(得分: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.theirdo.com”链接(象征性地或以其他方式)作为这样的目录:“/ www / hosts / saas.theirdomain.com / docs”在上面的例子中。

e.g。

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

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

答案 4 :(得分:0)

如果您的用户使用默认端口进行服务,则无需担心任何问题。只需告诉您的用户更改CNAME(别名)&amp; DNS管理器中的(主机)设置。

  

@ - &gt;将指向DOMAIN_NAME(如果他们想掩盖   他们的域名服务)。

     

saas - &gt;将指向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>

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