在express上伪造req.host值

时间:2014-03-29 06:40:57

标签: node.js express routes cname

我的网络应用程序以这种方式管理用户的个人资料:

username.mywebsite.com

我使用子域快速模块管理它,它工作正常。 (https://www.npmjs.org/package/subdomain

var subdomain = '/subdomain/:profileurl';
app.get(subdomain+'/user-home', main.isThisProfileExist, main.getHome);
app.get(subdomain+'/user-info', main.isThisProfileExist, main.getInfo);
app.get(subdomain+'/user-data', main.isThisProfileExist, main.getData);
...

然而,很少有用户有权将自己的个人资料与自定义域名(CNAME)相关联,这就是我的问题所在:我无法找到快捷路线的工作方式。所以我在考虑一种伪造expressjs的req.host值的方法。但我不认为这是最好的方式。

例如,用户已为其域名添加了此CNAME记录:

customdomain.com    CNAME    username.mywebsite.com

但是在express中我会得到req.host值:

customdomain.com

这是逻辑,但它不符合我对这种情况的需要,因为我无法知道哪个档案是针对性的......

你有什么想法帮助我吗?

谢谢

1 个答案:

答案 0 :(得分:1)

如果您不希望用户必须告诉您他们的自定义CNAME是什么,您可以在收到的主机上自行进行DNS查询。

类似的东西:

var dns = require('dns');
var domains = dns.resolveCname(req.host);

您可以使用connect:

轻松将其添加为您自己的中间件
app.use(myCustomDomainLookup());

中间件模块中的实现可能是这样的:

var dns = require('dns');

module.exports = function () {
    return function (req, res, next) {
        if (!recognisedSubdomain(req.host)) {
            var domains = dns.resolveCname(req.host);
            var validProfiles = domains.map(main.ifThisProfileExists);
            req._profile = validProfiles[0]; // Picking first valid profile
        }
        next();
    }
}

修改

为了清晰起见,请在此处添加评论代码。

要与您的子域中间件集成,您需要覆盖req.host。这意味着在子域中间件之前,您的中间件需要use d

你应该能够适应上述'如果'阻止如下:

if (!recognisedSubdomain(req.host)) {
    var domains = dns.resolveCname(req.host);
    req.host = domains[0];
}

由于resolveCname的文档表明可以返回域列表,因此如果返回多个域,您必须决定要执行的操作。