Как создавать субдомены в стиле клиент / клиент, используя Node и Express

Как разрешить клиентам доступ к SaaS, используя название своей организации в домене?

Например, у веб-приложения example.com может быть 2 клиента, OrgA и OrbB.

После входа каждый клиент перенаправляется на свой сайт orga.example.com / orgb.example.com.

Как только запрос, включающий субдомен, достигнет сервера узла, я надеюсь обработать запрос одним маршрутом '/'. Внутри обработчика маршрута он просто проверяет заголовок узла и рассматривает поддомен как параметр для организации. Что-то вроде:

app.get "/*", app.restricted, (req, res) ->
  console.log "/* hit with #{req.url} from #{req.headers.host}"
  domains = req.headers.host.split "."
  if domains
    org = domains[0]
    console.log org
    # TODO. do something with the org name (e.g. load specific org preferences)
  res.render "app/index", { layout: "app/app" }

NB. Первый элемент массива доменов - это название организации. Я предполагаю, что порт не отображается в заголовке хоста, и на данный момент я не рассматриваю, как обрабатывать субдоменные имена не-организаций (например, www, blog и т. Д.).

Поэтому у меня возник вопрос о том, как настроить узел / экспресс для обработки запросов с различными заголовками хоста. Обычно это решается в Apache с использованием псевдонима подстановочного знака или в IIS с использованием заголовка узла.

Примером Apache/Rails является @ http://37signals.com/svn/posts/1512-how-to-do-basecamp-style-subdomains-in-rails

Как можно добиться того же в узле?

3 ответа

Если вы не хотите использовать express.vhost, вы можете использовать http-proxy для достижения более организованной системы маршрутизации / портов

var express = require('express')
var app = express()
var fs = require('fs')

/*
Because of the way nodejitsu deals with ports, you have to put 
your proxy first, otherwise the first created webserver with an 
accessible port will be picked as the default.

As long as the port numbers here correspond with the listening 
servers below, you should be good to go. 
*/

var proxyopts = {
  router: {
    // dev
    'one.localhost': '127.0.0.1:3000',
    'two.localhost': '127.0.0.1:5000',
    // production
    'one.domain.in': '127.0.0.1:3000',
    'two.domain.in': '127.0.0.1:4000',

  }
}

var proxy = require('http-proxy')
  .createServer(proxyopts) // out port
  // port 4000 becomes the only 'entry point' for the other apps on different ports 
  .listen(4000); // in port


var one = express()
  .get('/', function(req, res) {
   var hostport = req.headers.host
   res.end(hostport)
 })
 .listen(3000)


var two = express()
  .get('/', function(req, res) {
    res.end('I AM APP FIVE THOUSAND')
  })
  .listen(5000)

У меня была похожая ситуация, хотя у меня был основной сайт example.com, где пользователь мог войти в систему и управлять своим сайтом, тогда OrgA.example.com был общедоступным сайтом, который обновлялся в зависимости от действий пользователя, вошедшего в систему. ком.

Я закончил тем, что создал два отдельных приложения и настроил виртуальные хосты внутри connect, чтобы указать "example.com" для одного приложения и "*" для другого. Вот пример того, как это сделать.

Я думаю, что любой запрос, поступающий на IP-адрес и порт сервера вашего узла, должен обрабатываться сервером вашего узла. Вот почему вы делаете vhosts в apache, чтобы различать запросы, которые получает apache, например, к поддомену.

Посмотрите на исходный код для экспресс-поддоменов, если вы хотите увидеть, как он обрабатывает субдомены ( исходный код состоит всего из 41 строки).

Другие вопросы по тегам