use dynamic subdomains with nodejs - node.js

hello i am new to Nodejs. I want to use dynamic subdomains to access my API and through subdomain prefix I can manage my API data.
Suppose I gave domain like domain:3000 and sub-domain could be a.domain:3000 or b.domain:3000 or anything prefixed to domain:3000.
I used wildcard-domains. but still unable to undersatnd the flow and how to use it and allow organisation listed in DB (Consider prefix as organisation name).
I have used following code:
var wildcardSubdomains = require('wildcard-subdomains')
var checkUser = subdomain('*.localhost:3000', function(req, res,
next) {
console.log(req.session.user.valid);
if(!req.session.user.valid) {
return res.send('Permission denied.');
}
next();
});
app.use(checkUser);
I am also using angularjs and using ui.router to change my states or urls.

I used this module
npm i vhost --save
Here you can see information
http://expressjs.com/en/resources/middleware/vhost.html
wildcard-subdomains
As you can see in https://www.npmjs.com/package/wildcard-subdomains
app.use(wildcardSubdomains({
namespace: 's', // __NAMESPACE_FROM_WILDCARD_CONFIG__
www: 'false',
}))
If you follow, example, link foo.localhost:3000 Express will process this middleware
app.get('/s/foo/', function(req, res){
res.send("Meow!")
})
That is to say
app.get('/__NAMESPACE_FROM_WILDCARD_CONFIG__/__SUBDOMAIN__/', function(req, res){
res.send("Meow!")
})
You can try to write app.get('/s/:subdomain', ...

Related

How to use only PART of the functionality in nested routes NodeJS

So I have a router schoolsRouter where all the school-specific functionality is being handled { login school, adding a new teacher, ...etc.). And I want the admin of the app to be able to add and delete new schools. Now the pattern I'm using encapsulates all the routing functionality in one file schools.routes.js where the School model is exposed. So the createSchool and deleteSchool routes are in the schools.routes.js but I need only the admin to be able to perform those operations and that seems pretty easy with merged routes like this (in admins.routes.js):
adminsRouter.use('/schools/', schoolsRouter);
but the problem is that now the admin can access all the other routes in schools.routes.js like schools/login which is something that I don't want to happen. So how can I make the adminsRouter use the create and delete operations from the schoolsRotuer without being able to access all these other functionalities? (Keeping in mind I'm using JWT authentication).
You could use middlewares in the routes that you wish to controll.
This is the middleware that I will name of admin-middleware.js
module.exports = (req, res, next) => {
if (user.admin === true) {
return next();
} else {
return res.status(403).send('Unauthorized')
}
}
So, this is your route declaration at schools.routes.js
const adminMiddleware = require('../YOUR_FOLDERS/admin-middleware.js');
schools.delete('/:id', adminMiddleware, (req, res) => {
return res.send('ok');
});
If you wish disregard a route, you can use this validation at your code in the middleware.
if(req.originalUrl.includes('/schools/login'))
return next();
I hope that it works to you.

Express: Disable headers for specific routes (Etag, set-cookie, etc)

For my application, we have rest API and the webapp server from the same app. (it is small enought not to have separate deployment)
Is there any way I can exclude all /api/* route paths to disable caching and cookies?
Note: I cannot do app.disable('etag') as it will disable for the entire webapp.
Afaik this is currently not possible - also there are a few open issues on github like this one for example: https://github.com/expressjs/express/issues/2472
As a workaround you could remove the headers for requests on the /api-route using something like this:
const onHeaders = require('on-headers')
// mount custom middleware for all api-requests
app.use("/api*", (req, res, next) => {
removeHeaders(res);
next();
});
function removeHeaders(res) {
onHeaders(res, () => {
res.removeHeader('ETag');
// remove other headers ...
});
}

Node express api routes for multilingual directory like url

Does any one knows an example or could explain here how node.js and express would have to route for a multilanguage site? I'm using i18n-node for translation and folder like routing ( /es/, /de/ , etc ) for different languages. This all are static routes but I also have routes like apiRoutes.route('/user/profile') using 'app' at the begining ( app.get('/app/user/profile') so please consider this in your answer so is NOT necesary route to : app.get('/es/app/user/profile') .
having 15 routes like this now:
app.get('/terms', function(req, res) {
res.render('terms',{
...
});
});
how it have to be set for routes like:
app.get('/es/terms', function(req, res) {
res.render('terms',{
...
});
});
Should I duplicate this routes and add for example a locale for
each like:
app.get('/es/terms', function(req, res) {
res.render('terms',{
...
});
});
Or Should do something like:
if cookie['lang'] && cookie['lang'] is in locales
// then redirect to /:lang/terms
else
// show default language in /terms
if req.headers["accept-language"] && req.headers["accept-language"]
// then redirect to /:lang/terms
else
//show default language in /terms
Or there is another way I should approach this that follows good practices or is better respecting standards?
Miro's Answer in :
How can I get the browser language in node.js (express.js)? says I should use app.all('*', ...
Is this all I need?, ..still, it might have a syntax error or i'm not understanding well this two parts
var rxLocal = /^\/(de|en)/i;
...
app.get(/\/(de|en)\/login/i, routes.login);
thanks in advance
You need to consider 2 things :
1. How get the local :
Accept-Language
The HTTP protocole define the Accept-Language header to manage the local. This is a normalized method. You can access it with the req.acceptsLanguages method of express.
+Normalized
+Natively support by brower
-Not easy to by passe by the end user
Path / Cookies
You can get the local from the path. In express it can be do with a parameter patter like /:local/rest/of/path and retrieve in the request object with the req.param method.
You can also get the information from the cookies with the req.cookies properties (don't forgot to set it).
Both
To increase the user experience you can mix the both method. For exemple get the default language from the HTTP header send by the browser but permite to the user to override this in you application and store this parameter in the cookies.
2. Use the local:
Each methods to get the local can be used from different way. I will
use random of them in exemple but they are all compatible.
Top level configuration.
In case of you use a template Engine and you controller can be local agnostic. You can use a middleware to get the local information and configure the render engine.
app.use('/:local' (req, res, next) => {
let localKey = req.param('local');
res.locals = // Some ingenious method to get the locales from localKey
next();
}
Check res.locals and your engine documentation.
Use it in controller.
If the local is part of the contoller process. You can get directly is value in controller.
In case of you use a complexe method to determine the final value of the local, you can also use a middleware to determine this value and enrich the request with it.
app.use((req, res, next) => {
let local = req.cookies.local;
if(!local) local = req.acceptsLanguages();
if(!local) local = 'en-US';
req.local = local;
}
Both
You can use both method too. It depend of what you need. Find the best way to get a maintainable code and avoid replication for your use case.
When you use middle where witch impact the controllers, be sure you declare them before your routes.
You can use a route parameter to get the locale from the URL, like this:
app.get('/:lang/terms', function (req, res) {
if (req.params === 'es') {
res.send('¡Hola!');
else {
res.send('Hi!');
}
});
The colon character tells Express to put whatever is between the first to slashes of the path in req.params.lang.
See express routing documentation for details.

Node Express auth status

I have multiple routes, split into different files (my app consists of different "modules", which I maintain in separate folders. For each folder, there is an index.js file in which I manage the routes per module, and I require these in the app.js file).
For every route, I will require to check the auth, and pass the loggedIn status to the header of every page:
//Default variables for the ejs template
var options = {
loggedIn: true
};
res.render("home/home", options);
If the logged in status is true, then the user's name will be displayed. If not, the login / signup labels are displayed.
What is the best way to centralise this, so that I don't need to require the auth script in every of these index.js (route) files?
I need to be able to pass the auth status to the view via the options object (see example).
In your auth, module, use a middleware function. That function can check and store res.locals.loggedIn which will be available for any view that will eventually be rendered. Just make sure the app.use call executes prior to your other routes and it will work properly.
app.use(function auth(req, res, next) {
res.locals.loggedIn = true; // compute proper value here
next();
});
From what I understand you need to do this for every request.One common thing is adding this as middleware so that all the request gets this .
For Example :
var http = require('http');
var connect = require('connect');
var app = connect();
app.use(function(req, res) {
res.end('Hello!');
});
http.createServer(app).listen(3000)
Now for every request , Hello is printed . You could extract this as a module and reuse it across projects. Check here for more details

Routing Engine for Node.js

I'm getting into Node.JS and would like to have flexibility on the routing engine. I want control over the mapping between urls comming and and what methods get fired.
I'd really like to setup placeholders in the route matching to automatically parse parameters too. Something like
{"routes": [
{'route': {'url': '/path/to/resource/[id]'}, "handler": idHandler()},
{'route': {'url': '/path/to/foo/[category]/bar'}, "handler": fooHandler(),
{'route': {'url': '/path/to/resource/'}, "handler": defaultHandler()}}
]};
You can choose a more specific solution (just for routing) like Director, or if you don't want to handle cookies, sessions, redirect functions etc your best option is Express.js or Flatiron (which you can use with Director).
I'll paste the code from the two so you can see how they can help in routing:
Express
app.get('/', function(req, res){
res.send('index page');
});
app.post('/login', function(req, res) {
// login logic
});
Director
//
// define a routing table.
//
var router = new director.http.Router({
'/hello': {
get: helloWorld
}
});
//
// You can also do ad-hoc routing, similar to `journey` or `express`.
// This can be done with a string or a regexp.
//
router.get('/bonjour', helloWorld);
router.get(/hola/, helloWorld);
Resources:
http://expressjs.com/en/guide/routing.html
http://blog.nodejitsu.com/scaling-isomorphic-javascript-code
http://blog.nodejitsu.com/introducing-flatiron
http://howtonode.org/express-mongodb
Yes, Express will be your best option, I think. No need to "re-invent the wheel" so to speak. You can do RegEx's on routes as well, which gives you a ton of flexibility. I suggest reading up on the guide...it has a lot of good info!
http://expressjs.com/en/guide/routing.html
Express.js and Connect have great support for routing, vhosts and a large number of extensions are available out there. For example simple integration of jade template rendering or less stylesheet processing.
Define routes with parameters, regular expressions and different HTTP methods.
app.get('/home', function(req, res) { });
app.post('/save/:contactID', function(req, res) { });
app.all('/params/:required/:andOptional?', function(req, res) { });
See kickstart and kickstart-example for an example of express with enabled jade and less processing.

Resources