Как blogger/wordpress/tumlr позволяют пользователям маскировать URL-адрес

Я создаю приложение saas. Пользователи имеют свой собственный URL-адрес, например пользователь.mysaasapp.com

Чтобы позволить пользователю иметь собственный URL-адрес, я использую mod rewrite. Что-то вроде http://mysaasapp.com/?user=user to user.mysaasapp.com (Это работает отлично)

Теперь я хочу предоставить пользователю гибкость для маскировки своего URL-адреса. Это означает, что пользователь может направить свой поддомен (saas.theirdomain.com) на user.mysaasapp.com. Как мне это сделать?

Я прочитал много статей (cname) на этом, но до сих пор не имеет определенного решения. Мне интересно, как делают такие крупные компании, как wordpress/google.

e.g http://www.tumblr.com/docs/en/custom_domains

e.g http://developer.uservoice.com/docs/site/domain-aliasing/

Я понимаю, что компании возьмут этот процесс:

  • Получить пользователя для добавления cname
  • Попросите пользователя ввести свой домен в приложение saas (возможно, в пользовательском домене)

Что мне нужно, чтобы это работало? Спасибо!

Ответы

Ответ 1

Если Im right вы можете использовать wild card в ServerAlias, а с помощью mod_rewrite вы можете переписать его в нужный файл, чтобы ваши vhosts стали похожими на

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

и ваш CNAME будет выглядеть как

*.mysaasapp.com IN CNAME mysaasapp.com

Я надеюсь, что это поможет

EDIT:

изменить vhosts на

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

и замените [STANDARDFOLDER] на DocumentRoot mysaasapp.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 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
}

Это действительно грязное решение вашей проблемы Надеюсь, теперь это работает для вас.

UPDATE:

сначала я не знал, что вы также хотите перенаправить из пользовательского домена,

то они должны добавить CNAME на свой DNS-сервер/менеджер с помощью

theirdomain.com IN CNAME thierusername.mysaasapp.com

и если ваши записи DNS так, что все поддомены идут на ваш apache, если он будет работать с кодом и Vhosts, которые я вам дал

ОБНОВЛЕНИЕ 2:

lanzz просто указал на то, что я забыл (facepalm), проверяя заголовок HOST, что не имеет смысла, потому что у него будет customdomain.com, поэтому вам нужно спросить своих пользователей о своих доменах (если у вас нет общего IP-адреса, с CNAME, и если у вас нет общего IP-адреса, вы можете позволить им указывать на ваш IP-адрес с записью A) и искать домен из 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 yours and if it 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 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;
}

Ответ 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, чтобы она стала

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

Я сделал несколько предположений здесь, но так, как я это делал в прошлом, исключая любые опечатки, конечно.

Ответ 3

Поскольку вы хотите обрабатывать любое имя хоста, которое было создано на вашем сайте, вам нужно будет иметь свой сайт на вашем основном виртуальном хосте (тот, который появляется первым в вашей конфигурации). Основной виртуальный хост будет обрабатывать все запросы для имен хостов, которые не имеют определенного виртуального хоста, определенного для своего имени хоста.

В вашем коде вы должны проверить $_SERVER['HTTP_HOST'] и определить соответствующего пользователя. Вам нужно будет обрабатывать четыре разных случая:

  • Запрос предназначен для вашего основного домена (или www.yourmaindomain), и в этом случае у вас нет соответствующего пользователя
  • Запрос для субдомена в вашем основном домене (например, foouser.yourmaindomain), то вы знаете, что запрос для foouser
  • Запрос не содержит ничего, но у вас есть пользователь, настроенный на использование этого имени хоста. Вам необходимо будет поддерживать эти назначения между пользователями в вашем коде, что выходит за рамки этого вопроса.
  • Запрос ни для одного из вышеперечисленных; кто-то указал на имя хоста на ваш IP по ошибке или указал неверное имя хоста, или имя хоста еще не назначено пользователю, или кто-то просто пытается получить неправильное имя хоста на вашем IP-адресе по какой-либо причине. Вам нужно будет отобразить какую-то неизвестную страницу для этого случая.
Решение

@EaterOfCorpses, по-видимому, предполагает, что вы сможете определить, какое имя хоста указывает пользователь CNAME; это редко бывает и будет сильно зависеть от пользовательского браузера (т.е. браузер должен включать Host: <CNAME target> вместо Host: <original hostname> в HTTP-запросе, но браузеры предоставляют исходное имя хоста, используемое в URL-адресе, которое все равно будет пользователем пользовательский домен, а не username.yourdomain, отмеченный записью CNAME).

Ответ 4

Предполагая, что вы используете 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.

Ответ 5

Если ваши пользователи используют порт по умолчанию для ваших услуг, вам не нужно ни о чем беспокоиться. Просто сообщите своим пользователям об изменении настроек CNAME (Alias) и A (Host) в диспетчере DNS.

@- > указывает на 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 alias.
DocumentRoot USER_FOLDER 
</VirtualHost>

Я надеюсь, что это решит вашу проблему.