express-subdomain
express-subdomain copied to clipboard
Static content served on other subdomains
So I have run into a problem with content on subdomains that shouldn't be there being there.
Let's assume that I have a folder of static content that should only be served on example.com
. In this folder I have a file foo.png
I will be using this code:
app.js:
// deps and stuff
app.use(express.static(path.join(__dirname, 'static')));
fs.readdirSync('./modules').forEach((mod, index, array) => {
if(mod.endsWith('.js')) {
let name = mod.substring(0, mod.length - 3)
console.log(`Loaded module: ${name}`)
app.use(subdomain(name, require(`./modules/${mod}`)))
}
})
// other server stuff
modules/test.js
//deps n stuff
router.get('/', (req, res, next) => {
res.send("Hi, this test worked.");
});
module.exports = router
I would expect http://example.com/foo.png
to return the picture, which it does.
I would also expect http://test.example.com/foo.png
to return a 404 not found, but it returns foo.png as well.
How would I get my static content to only show on the domain example.com
?
I tried app.use(subdomain('', staticContentRouter))
but it throws an error.
+1 Yep, I'm running into the same problem, too.
In addition, If you have a router in your root route. You can access the same route from any other subdomain if the route isn't in use for that subdomain.
I don't know if this issue exists when you deploy your project into a real server. But, it's there on localhost and it's really annoying.
I was about to submit a pull request and hack out a solution, then it dawned on me!
Here is the solution, sooo simple....
Place this line
app.use(express.static(path.join(__dirname, 'static')));
before...
express.Router()
Example
app.use(express.static(path.join(__dirname, 'static')));
app.dispensary = app.express.Router()
app.use( require('express-subdomain')('dispensary', app.dispensary))
require('fs').readdirSync('./controllers/').forEach(controller => {
require('./controllers/' + controller)(app)
})
:-)
Remember, the best way to serve static content is with NGINX, not NODEJS!
nginx.conf
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name static.indospace.io;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_certificate /etc/letsencrypt/live/www.indospace.io-0022/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.indospace.io-0022/privkey.pem;
ssl_dhparam /etc/nginx/dhparam_2048.pem;
ssl_prefer_server_ciphers on;
ssl_ciphers "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS";
ssl_session_timeout 59m;
ssl_session_cache shared:SSL:59m;
ssl_session_tickets on;
ssl_stapling on;
ssl_stapling_verify on;
#resolver 8.8.4.4 8.8.8.8;
#resolver_timeout 5s;
add_header Access-Control-Allow-Origin "*";
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff";
add_header X-XSS-Protection 1;
allow all;
gzip on;
gzip_http_version 1.0;
gzip_vary on;
gzip_comp_level 6;
gzip_proxied any;
gzip_types application/javascript application/rss+xml application/vnd.ms-fontobject application/x-font application/x-font-opentype application/x-font-otf application/x-font-truetype application/x-font-ttf application/x-javascript application/xhtml+xml application/xml font/opentype font/otf font/ttf image/svg+xml image/x-icon text/css text/javascript text/plain text/xml;
gzip_buffers 16 8k;
include /etc/nginx/mime.types;
location ~* ^.+\.(jpeg|jpg|png|gif|bmp|ico|svg|css|js|scss|map|less|woff|woff2|otf|eot|ttf)$ {
expires 30d;
}
fastcgi_hide_header Set-Cookie;
root /etc/nginx/www/static;
}
To solve this is simple, just add app.set('subdomain offset', 1)
to your "server.js" file.
This happens because the subdomain offset is set to 2 by default. Therefore any request to example.localhost
will not work because example
and localhost
don't count as subdomains. However, requests to api.example.localhost
would work because api
would count as a subdomain.
When setting the offset to 1 example
counts as a subdomain, resolving this problem