如何使用Node和Express创建客户/客户端风格的子域



如何允许客户使用其在域中的组织名称访问SaaS?

例如,一个网络应用程序example.com可能有两个客户,OrgA和OrgB。

登录后,每个客户都会被重定向到他们的网站orga.example.com/org.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" }

注:。域数组中的第一项是组织名称。我假设主机头中没有出现端口,目前,我还没有考虑如何处理非组织子域名(如www、博客等)。

我的问题更多的是关于如何配置node/express来处理具有不同主机头的请求。这通常在Apache中使用通配符别名或在IIS中使用主机头来解决。

Apache/RRails的一个例子是@http://37signals.com/svn/posts/1512-how-to-do-basecamp-style-subdomains-in-rails

如何在节点中实现相同的功能?

如果你不想使用express.vhost,你可以使用http代理来实现更有组织的路由/端口系统

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)

我认为任何到达节点服务器的IP地址和端口的请求都应该由节点服务器处理。这就是为什么您在apache中创建vhosts,例如通过子域来区分apache接收的请求。

如果你想看看express子域的源代码是如何处理子域的(源代码只有41行)。

我也遇到过类似的情况,尽管我有一个用户可以登录和管理其网站的主站点example.com,但OrgA.example.com是一个面向公众的网站,将根据登录用户在example.com上的操作进行更新。

我最终创建了两个独立的应用程序,并在connect-to-point中设置了虚拟主机"example.com"指向一个应用程序,"*"指向另一个。下面是一个如何做到这一点的例子。

最新更新