I'm trying to redirect a user based on their url path and also if they do not have a particular cookie set.
How do I get nodejs to "do nothing" and continue? The request just hangs if it's executing the else statement. If I remove the else statement the request just hangs as well.
app.get('/*', function (req, res) {
if( !(typeof req.cookies['isLoggedIn'] !== 'undefined' && req.cookies['isLoggedIn'] === true ) && req.url.substring(0, 7) != '/login/' ) {
res.send(403, "You are not logged in");
}else{
//do nothing
}
return;
});
You need to use the next callback to indicate your middleware doesn't have anything else to do.
app.get('/*', function (req, res, next) {
if( !(req.cookies.isLoggedIn !== void 0 && req.cookies.isLoggedIn === true) && req.url.substring(0, 7) != '/login/' ) {
res.send(403, "You are not logged in");
}else{
next();
}
});
You need to put an output.
for example
res.send(200, "You arelogged");
otherwise, your browser will still be waiting for an output.
what do you mean by "continue?"
Related
I am relatively new to NodeJS and have run into an issue. Incoming request from Angluar UI has two parameters (loginId and password) and on Node, I am reading the data from a local json file, iterating through the 'users' array and based on the matching params, I am sending the particular object in the server response. However, my logic is failing where there are multiple objects in the 'users' array and I have to send a server response for the not-matched one as well. I know that I cannot send multiple responses but that is where i need the help. Any help will be highly appreciated.
Here is the code:
if (jsonData.users.length > 0) {
jsonData.users.forEach(user => {
if ((reqBody.loginId === user.email || reqBody.loginId === user.mobile) && reqBody.password === user.password) {
res.send({ 'userData': user });
} else {
res.json({ 'userData': 'No records found' });
}
})
res.send ends the response.
So using it a second time it will not send anything.
https://www.nodejsconnect.com/blog/articles/sending-multiple-http-responses-expressjs
EDIT:
I'm not completely sure what you want, but I think you want to do something like this.
-> return the user for whom the userId and password matches or return 'no records found' ( or even better send an 401 - unauthorized - status code)
const user = jsonData.users.find(user => (reqBody.loginId === user.email || reqBody.loginId === user.mobile) && reqBody.password === user.password));
if (user) {
res.send({ 'userData': user });
} else {
res.json({ 'userData': 'No records found' });
// or res.sendStatus(401); // unauth
}
Try this... If you wanna break the loop after a match.
if (jsonData.users.length > 0) {
let isMatch = false;
jsonData.users.forEach(user => {
if ((reqBody.loginId === user.email || reqBody.loginId === user.mobile) && reqBody.password === user.password) {
isMatch = true;
return res.send({ 'userData': user });
}
})
if(!isMatch)
res.json({ 'userData': 'No records found' });
}
So, here is the problem. I found how to do http request in Node.js, so that I could download and parse remote JSON file. It all works fine but nothing happens after that. I have a function and in that there is if condition that doesn't get executed. It simply cannot get past the http request. Is there something I am missing?
var remoteStamp;
if (typeof force == "undefined") {
var timeurl = "http://" + parsedconfig.weburl + "/timestamp.json";
request(timeurl, { json: true }, (err, res, body) => {
if (err) { return console.log(err); }
console.log(body.timestamp);
remoteStamp = body.timestamp;
});
}
if (remoteStamp < parsedconfig.timestamp || force == "local") {
//something should happen here, all the values check out - still nothing happens
}
you are using callback so all the code which you want to execute after request is completed should be inside the callback
var remoteStamp;
if (typeof force == "undefined") {
var timeurl = "http://" + parsedconfig.weburl + "/timestamp.json";
request(timeurl, { json: true }, (err, res, body) => {
if (err) { return console.log(err); }
console.log(body.timestamp);
remoteStamp = body.timestamp;
if (remoteStamp < parsedconfig.timestamp || force == "local") {
//something should happen here, all the values check out - still nothing happens
}
});
}
Or you can use request-promise library to do this in promises. https://github.com/request/request-promise
On how to use promises: https://developers.google.com/web/fundamentals/primers/promises
I am trying to use express then next('route') but I am not finding much in the docs on how to do this, it is mentioned here. But it doesn't explain how to do the
will work only in middleware functions that were loaded by using the app.METHOD() or router.METHOD() functions.
I don't get what they mean by that because I have never used app.METHOD() before and again am unable to find docs on how to do it properly with the next('route'). Would this work?
app.method('*', (req, res, next) => {
if(req.user == null) {
next();
} else {
User.findOne({"_id": req.user.id}, function(err, result) {
if(err){
console.log(err);
} else {
if(stripe.active == false && stripe.trial == false){
res.render('/dashboard/billing');
next('route');
} else {
next();
}
}
});
}
});
Would that even work? I am guessing somewhere in there I messed up something. If I did that right then it would find a user, then check is both is_active and is_trial are false and if so skip onto the next route. The idea of me doing this is so that a use can any part of the site that doesn't have a logged in user then when there is a logged in user and both are false I only let them go to /dashboard/billing. This was suggested to me as a way to prevent users who have not paid yet their trial is over from accessing my application.
Route I am testing on:
// dashboard
app.get('/dashboard',
setRender('dashboard/index'),
setRedirect({auth: '/login'}),
isAuthenticated,
(req, res, next) => {
},
dashboard.getDefault);
First of all, change the method to the right HTTP method request. In the documentation, it specifies what .METHOD() represents:
app.METHOD() functions, where METHOD is the HTTP method of the request
that the middleware function handles (such as GET, PUT, or POST) in
lowercase.
In other words, .METHOD() is a place holder for .get, .post, .put, etc.
Try changing that in your app:
app.get('*', (req, res, next) => {
if(req.user == null) {
next();
} else {
User.findOne({"_id": req.user.id}, function(err, result) {
if(err){
console.log(err);
} else {
if(stripe.active == false && stripe.trial == false){
res.render('/dashboard/billing');
next('route');
} else {
next();
}
}
});
}
});
See if you can work it out from there.
Update
Calling .next('route') right after res.render() cancels res.render() because .next('route') will send the request to the next router.
I'm newish to NodeJS and ExpressJS and am trying to get the session management flow in main.js worked out.
What I currently have that's working:
app.get('*', function(req, res){
var page = getPage();
session_.initSession( req, res, function( ){
loggedIn = false;
if( req.session && typeof req.session.username !== "undefined" ){
loggedIn = true;
userFName = req.session.first_name;
userLName = req.session.last_name;
}
if( !loggedIn ){
res.render('pages/login', { message: "<div class='notice centered' style='width: 40%;'>Please login</div>" });
returnFlag = true;
return;
} else {
if (page.length < 1){
// render index page here ...
returnFlag = true;
return;
}
// render 'test' page
if( page == 'test' ){
// do test functions here...
returnFlag = true;
return;
}
}
});
if( returnFlag == true ){
return;
}
res.render('partials/home', { message: "404 not found (unknown page GET request)" });
return;
});
app.post('*', files, function(req, res){
var page = getPage();
if( page == 'test' ){
// do test functions here...
returnFlag = true;
return;
}
if( returnFlag == true ){
return;
}
res.render('partials/home', { message: "404 not found (unknown page POST request)" });
return;
});
The problem with this is that POST requests are being processed even when no session is in place. I've tried adding app.all/use blocks above the app.get and app.post code blocks to set up a session, but then the app.get/post blocks were not getting processed. What is the optimal way to architect this so all requests get filtered through session management and then on to page request blocks if a proper session is in place?
A Middleware function in Express is what you're looking for.
Middleware functions are functions that have access to the request object (req), the response object (res), and the next middleware function in the application’s request-response cycle. The next middleware function is commonly denoted by a variable named next.
Learn more from Express's Documentation - here
A Middleware can be connected like a chain and is processed in the sequence you write it in. As long as you're executing the 'Next' function, you can link as many as you would like.
So before the POST requests are actually processed, you can exit out and redirect the user, otherwise execute the next function to continue processing.
Here is an example of how you could simplify your code.
function _sessionAuthorization(req, res, next) {
if(typeof req.session.username == "undefined") {
return res.redirect("/login");
} else {
next();
}
}
app.get('*', function(req, res){
res.render('partials/home', { message: "404 not found (unknown page GET request)" });
});
app.post('*', files, _sessionAuthorization, function(req, res){
res.render('partials/home', { message: "404 not found (unknown page POST request)" });
});
ok i had a piece of code doing login using passport. Now based on different linux distribution i want to do it differently.
function loginDispatch(osType) {
if(osType == "sles") {
passport.authenticate('myWorkingAuth');
}
else if(osType == "ubuntu") {
passport.authenticate('local');
}
else {
console.log("error");
}
}
app.post('/login', loginDispatch(osInfo), function (req, res, next) {
next();
}, function(req, res) {
logger.trace('login called with user = ' + req.user.name);
//save the user in our session
req.session.user = req.user;
// ..............
res.send(req.session.user);
});
But it gives such error in Ubuntu:
Error: Route.post() requires callback functions but got a [object Undefined]
How to fix it please ? Thanks !
You are passing the result of loginDispatch as middleware. loginDispatch therefore needs to return a function. Amend your function to return the appropriate passport middleware:
if(osType == "sles") {
return passport.authenticate('myWorkingAuth');
}
else if(osType == "ubuntu") {
return passport.authenticate('local');
}
else {
console.log("error");
}
As an aside, you probably want to handle the final else a little more robustly, but I'm assuming this is test code and you know that :)