Question

My web application manage user's profile this way:

username.mywebsite.com

I manage this with a subdomain express module and it works fine. (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);
...

However few users have the rights to link their profile with their custom domain name (CNAME), and this is where my problem start : I cant find a way for my express routes to work. So I was thinking about a way to fake the req.host value of expressjs. But I don't think it is the best way to proceed.

For example the user has added this CNAME record for his domain name:

customdomain.com    CNAME    username.mywebsite.com

But in express I will get the req.host value:

customdomain.com

It's logic but it doesn't fit my need for this case because I have no way to know which profile is targeted...

Have you got any idea to help me out ?

Thank you

Was it helpful?

Solution

If you don't want your users to have to tell you what their customised CNAME is, you can do a DNS lookup yourself on the host that you receive.

Something like:

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

You can easily add this as your own middleware using connect:

app.use(myCustomDomainLookup());

An implementation in a middleware module might be something like this:

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();
    }
}

EDIT:

Adding code from comment here for clarity.

To integrate with your subdomain middleware, you'll need to override req.host. This means your middleware will need to be used before the subdomain middleware.

You should be able to adapt the above 'if' block as follows:

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

Since documentation for resolveCname indicates a list of domains can be returned, you'll have to decide what you want to do if more than one is returned.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top