bmullan91 / express-subdomain

Super simple subdomain middleware for expressjs
414 stars 49 forks source link

How i create a sub domain for each user? #26

Closed myexpertiseforyou closed 7 years ago

myexpertiseforyou commented 8 years ago

I am working on MEAN application. I want to create a unique subdomain for each user. If any one visit that unique sub domain then information will show accordingly.How i will handle this in local as well production? I don't want to use A record because i need this in dynamic way.

Thanks in advance

rusintez commented 8 years ago

what about dynamic A ? eg. *.domain.com points to domain.com?

then in your router


// get your dynamic subdomain

app.use(function(req, res, next) {
  if (!req.subdomains.length || req.subdomains.slice(-1)[0] === 'www') return next();
  // otherwise we have subdomain here
  var subdomain = req.subdomains.slice(-1)[0];
  // keep it
  req.subdomain = subdomain;
  next();
});

// render a page
app.get('/', function(req, res) {
  // no subdomain
  if (!req.subdomain) {
    // render landing page
    res.render('home');
  } else {
    // render subdomain specific data
    res.render('user-page', { subdomain: req.subdomain });
  }
});
myexpertiseforyou commented 8 years ago

@rusintez Thanks for quick response I want like this My main domain is www.demo.com. Now if user surendra create a new account then he can access surendra.demo.com instantly. so i can dynmic handle subdomain. How i can setup it local also

Thanks in advance

rusintez commented 8 years ago
  1. for local wildcard subdomain development check something like http://pow.cx/ - it works with node.js
  2. the example above is exactly what you need in order to serve user-specific content based on subdomain.
myexpertiseforyou commented 8 years ago

Thanks for your quick response. I got your point and i know it will work now query is that how i point 'N' number of sub domain. Each new user i want to create sub domain. Can i handle this without enter in etc/host file.

Thanks in advance

rusintez commented 8 years ago

yes

bmullan91 commented 8 years ago

@surendrakumar1992 Did you figure out a solution?

LotharVM commented 7 years ago

Hi all,

@surendrakumar1992's question is exact my situation. @rusintez's answer looks good, but is not including any 'does the user exists-check', right? As the subdomain should be available after registration, it should not be accessible before the username is registered.

I'm using Passportjs for authentication in my app, where a user's username will be the subdomain. Any suggestion how to achieve my required 'subdomain only available if username exists' situation?

Really appreciated!

Regards, Lothar

rusintez commented 7 years ago

@LotharVM, like in example above


// render a page
app.get('/', function(req, res) {
  // no subdomain
  if (!req.subdomain) {
    // render landing page
    res.render('home');
  } else {
    // render subdomain specific data
    User.findOne({ subdomain: req.subdomain }, function(err, user) {
      if (!err && user) {
        return res.render('user-page', { user: user });
      } else {
        // no user with this subdomain
        res.render('404');
      }
    });
  }
});

Hope this makes sense.

LotharVM commented 7 years ago

@rusintez, that makes perfect sense! Although I cannot make it work completely.. The first part is working fine; when I go to domain.com it shows the homepage and when I go to sub.domain.com it shows me the signup page.

The problem is that it always shows me the signup page, even when the subdomain matches a username in the database. I changed { subdomain: req.subdomain } in your code to { username: req.subdomain } as I'm using the username field in MongoDB to store the usernames. I'm not sure if that's the correct way, but when I copy/paste your code it isn't working either - it gives me the same result..

// render a page
app.get('/', function(req, res) {
  // no subdomain
  if (!req.subdomain) { 
  // render landing page
     res.render('home');
   } else {
   // render subdomain specific data
   User.findOne({ username: req.subdomain }, function(err, user) {
     if (!err && user) {
       res.render('contact');
     } else {
       // no user with this subdomain
       res.render('account/signup');
     }
   });
 }
});
rusintez commented 7 years ago

Do you have this code preceding your route?


// get your dynamic subdomain

app.use(function(req, res, next) {
  if (!req.subdomains.length || req.subdomains.slice(-1)[0] === 'www') return next();
  // otherwise we have subdomain here
  var subdomain = req.subdomains.slice(-1)[0];
  // keep it
  req.subdomain = subdomain;
  next();
});
LotharVM commented 7 years ago

@rusintez Yes! I think the problem lies in this part:

    User.findOne({ subdomain: req.subdomain }, function(err, user) {
      if (!err && user) {
        return res.render('user-page', { user: user });
      } else {
        // no user with this subdomain
        res.render('404');
      }
LotharVM commented 7 years ago

I got it working!

User.findOne({ subdomain: req.subdomain }, function(err, user) {

should be

User.findOne({ 'profile.subdomain': req.subdomain }, function(err, user) {

Because my username field is a subfield of 'profile'. Stupid mistake..

Thanks for the help @rusintez 👍

bbbneo333 commented 7 years ago

this "issue" can be closed now @bmullan91

juliocanares commented 7 years ago

I think @rusintez you mean a CNAME record, because you are pointing to an hostname not ip

biplabmalakar commented 6 years ago

Gd mrng everyone. I am new in angular and node.js. Now I am tring to make subdomain for each user and I am able to make by the above code. Now question is when user request for my page he/she need to enter my register domain, so question is how i can run my web application using user register subdomain. Means if enter app.example.com---> application 1 biplab.example.com---> apllication1 And in my case i am not able to render web page from my server, because my server(node.js) and web page(angular2) are seperate. I can only verify the user by server.

juliocanares commented 6 years ago

@biplabmalakar is your web app an static one? or is it serve by a serve you control?

  1. You can get the subdomain from the window.location.href, and then send a request to your server to get the user info.
  2. Get the subdomain with this library and send it to the your server too.
biplabmalakar commented 6 years ago

@juliocanares Thank u for response. Data is serve by the server, for that i make request. Means I don't need to alias my domain name by each user selected name. When I create domain in server It will run my angular application automatically and using subdomain name i can retrive user data from server.

abdokouta commented 6 years ago

@rusintez i'm interesting about the example u provide but in my situation i would like to integrate company account like companyname.myproject.com then after validating company name it will redirect the user to login my point is to create company account so that it have all company data and users and there is a lots of website doing that the most popular is slack any suggestions or ideas?

rusintez commented 6 years ago

@abdokouta, same as in above code.

msameerbm commented 6 years ago

In my etc/hosts file:

127.0.0.1 smallscale.com 127.0.0.1 hello.smallscale.com

I am using this library and its working good, if i hit smallscale.com i get one route, if i hit subdomain url its correctly going into another route.

My Question is i am putting this:

app.use(subdomain('hello', router)); // putting hello static in my express file

Any way to use dynamically? i mean dynamic number of sub-domains? with out putting static router file in my express code?

rusintez commented 6 years ago

yes, @sameercodes. just like above in #issuecomment-225441455

msameerbm commented 6 years ago

@rusintez yes its working! but if this works there is no use of this library? because the above code is working without this library! 😛

rusintez commented 6 years ago

how about https://github.com/bmullan91/express-subdomain#wildcards ?

msameerbm commented 6 years ago

I dont know about that wilcards ! @rusintez

But this one perfectly working

Hi friends i got solution for dynamic domain to work locally:

Use nginx as a server!

If use using apache server, stop that and install nginx

first add all your domains and subdomains in /etc/hosts: (without this you can't able to make work in local system)

127.0.0.1 github.com 127.0.0.1 sameer.github.com

edit your nginx.conf file: Set a nginx reverse proxy

Add your node js project port, in my project i am using 5000, so i put 5000

server {
        listen 80;
        server_name github.com; 
        location / {
            proxy_pass         http://localhost:5000; 
            proxy_http_version 1.1;
            proxy_set_header Host      $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
    server {
            listen 80;
            server_name *.github.com;
            location / {
                proxy_pass         http://localhost:5000; 
                proxy_http_version 1.1;
                proxy_set_header Host      $host;
                proxy_set_header X-Real-IP $remote_addr;
            }
        }

Instead of app.use(subdomain('yourstuff', router)); // static way Place the below code:

// get your dynamic subdomain
app.use(function(req, res, next) {
  if (!req.subdomains.length || req.subdomains.slice(-1)[0] === 'www') return next();
  // otherwise we have subdomain here
  var subdomain = req.subdomains.slice(-1)[0];
  // keep it
  req.subdomain = subdomain;
  next();
});

// render a page
app.get('/', function(req, res) {
  // no subdomain
  if (!req.subdomain) {
    // render landing page
    res.render('home');
  } else {
    // render subdomain specific data
    res.render('user-page');
  }
});