too many redirects in express - node.js

I want to handle all my cookies and session stuff in a function then redirect to the destination path. I use this function in Express:
app.all('*', function(req, res, next){
if('_id' in req.session)
next()
else if('userInfo' in req.cookies){
req.session._id = req.cookies.userInfo._id
next()
} else {
res.redirect('../login')
}
res.end()
})
but browser print this error:
net::ERR_TOO_MANY_REDIRECTS
what's the problem?

This error occurs when a web browser is redirecting you to another web page which then that web page redirects you back to the same browser again. Your configurations are wrong. app.all('*', ..) runs again and again whenever a request is made, which causing repetition.
You need to have better configurations than app.all(*..) //all. You need to specify it more so that it doesn't repeat itself.
I would say limit it down to some urls and not all of them. You could do
app.get('/cookieCheckerPage', function(req, res){
//code here
});
Also please see Error 310 (net::ERR_TOO_MANY_REDIRECTS):

Related

get host WITH PORT from request

I am trying to redirect to the original page after a login redirect. I have some middleware which checks if the user is logged in and if not redirects to the login page. code below
middlewareObj.isLoggedIn = function(req, res, next){
if(req.isAuthenticated()){
return next();
}
res.redirect("/login");
};
I am trying to get the full url from the request and tack it on the the end of the login URL so that after the login, I can redirect. According to the nodejs. docs I should be able to pull this info using req.host + req.originalURL. However, when I do that, it just pulls the hostname without pulling the port. in other words, it just returns localhost/pathname instead of localhost:3000/pathname. node js docs say that req.host should return the port while req.hostname should return just the hostname, but I'm getting the same output either way.
Thanks so much for any help!
req.header('Host') should get the HTTP Host header which will contain the port.

How to use authenticated middleware properly in nodejs

I just started working on node using express framework.
app.use('/', auth, users);
and this is my route file
router.get('/' , function(req, res, next) {
render("dashboard");
});
router.get('/first' , function(req, res, next) {
//first request
});
router.get('/second' , function(req, res, next) {
//second request
});
so on...
My question is, when i pass middleware it checks for every request whether its authenticated or not using passportjs, but suppose i have a dashboard and i am sending 10 ajax requests to grab data for the widgets. So only for dashboard it will call deserialize function 11 times ,first to render the page and then for 10 ajax request. I read answer given over here,
How to properly use Passport.js?
But is it fine to go with this approach?
Yes, it is fine to go with this approach if you don't want to have security issues. You have to check the user for every request, it is very simple someone to check the network tab in the browser debugger, understand what's going on and then start spoofing your requests. You can't sacrifice security for performance because you want to execute few query less.

Node Express - res.redirect() not behaving as expected

I am trying to redirect to a login page after successfully logging a user out, but am having an issue when calling res.redirect() from my logout route handler in express.
I have the following middleware to redirect a user to a login page (note I am using express-session too)
//A request to '/login' will serve the login page
app.use('/login', function(req, res){
res.sendFile(path.join(__dirname+'/public/login.html'))
});
//This will listen for all requests
app.use(function(req, res, next) {
//Here we only want to redirect to the logic route (above) if the request is not
//a login action and there is no access token present on the session object
if (req.url!== '/auth/login' && !req.session.accessToken) {
res.redirect('/login');
} else {
next();
}
});
This redirect above works as expected.
When a user performs a logout, I handle like so:
app.post('/auth/logout', function(req, res){
req.session.destroy();
res.redirect('/login');
});
I can see in Chrome debugger, the network tab shows my login view is being served back to the browser, but the browser window does not change. I notice the login.html is being returned with a 304 code too if that has any relevance. I'm feeling a bit dumb but am failing to see what's different here, can someone shed some light please?
Thanks

ExpressJS : res.redirect() not working as expected?

I've been struggling for 2 days on this one, googled and stackoverflowed all I could, but I can't work it out.
I'm building a simple node app (+Express + Mongoose) with a login page that redirects to the home page. Here's my server JS code :
app
.get('/', (req, res) => {
console.log("Here we are : root");
return res.sendfile(__dirname + '/index.html');
})
.get('/login', (req, res) => {
console.log("Here we are : '/login'");
return res.sendfile(__dirname + '/login.html');
})
.post('/credentials', (req, res) => {
console.log("Here we are : '/credentials'");
// Some Mongoose / DB validations
return res.redirect('/');
});
The login page makes a POST request to /credentials, where posted data is verified. This works. I can see "Here we are : '/credentials'" in the Node console.
Then comes the issue : the res.redirect doesn't work properly. I know that it does reach the '/' route, because :
I can see "Here we are : root" in the Node console
The index.html page is being sent back to the browser as a reponse, but not displayed in the window.
Chrome inspector shows the POST request response, I CAN see the HTML code being sent to the browser in the inspector, but the URL remains /login and the login page is still being displayed on screen.
(Edit) The redirection is in Mongoose's callback function, it's not synchronous (as NodeJS should be). I have just removed Mongoose validation stuff for clarity.
I have tried adding res.end(), doesn't work
I have tried
req.method = 'get';
res.redirect('/');
and
res.writeHead(302, {location: '/'});
res.end();
Doesn't work
What am I doing wrong? How can I actually leave the '/login' page, redirect the browser to '/' and display the HTML code that it received?
Thanks a million for your help in advance :)
The problem might not lie with the backend, but with the frontend. If you are using AJAX to send the POST request, it is specifically designed to not change your url.
Use window.location.href after AJAX's request has completed (in the .done()) to update the URL with the desired path, or use JQuery: $('body').replaceWith(data) when you receive the HTML back from the request.
If you are using an asynchronous request to backend and then redirecting in backend, it will redirect in backend (i.e. it will create a new get request to that URL), but won't change the URL in front end.
To make it work you need to:
use window.location.href = "/url"
change your async request (in front end) to simple anchor tag (<a></a>)
It's almost certain that you are making an async call to check Mongoose but you haven't structured the code so that the redirect only happens after the async call returns a result.
In javascript, the POST would look like something this:
function validateCredentials(user, callback){
// takes whatever you need to validate the visitor as `user`
// uses the `callback` when the results return from Mongoose
}
app.post('/credentials', function(req, res){
console.log("Here was are: '/credentials'";
validateCredentials(userdata, function(err, data){
if (err) {
// handle error and redirect to credentials,
// display an error page, or whatever you want to do here...
}
// if no error, redirect
res.redirect('/');
};
};
You can also see questions like Async call in node.js vs. mongoose for parallel/related problems...
I've been working on implementing nodemailer into my NextJS app with Express. Was having this issue and came across this. I had event.preventDefault() in my function that was firing the form to submit and that was preventing the redirect as well, I took it off and it was redirecting accordingly.
Add the following in your get / route :
res.setHeader("Content-Type", "text/html")
Your browser will render file instead of downloading it

properly handle a 404 in expressjs

A little baffled at how to best handle 404 cases in my app. Here is a gist of a very basic example.
//******************************
// BUILD THE HTTP SERVER
//******************************
var express = require('express');
var app = express.createServer();
app.get('/login', function(req, res){
console.log("hit the login");
res.send('you hit the login');
});
app.get('*', function(req, res){
console.log("got a 404");
res.send('what???', 404);
});
app.listen(8081);
console.log('Server started on port: 8081');
If I fire up the server and hit the index of the server "/" I properly get the 404 message, HOWEVER, in the logs are 2 "got a 404" log entries on the console... odd.
So if I hit the "/login" page I do get the proper page, and corresponding message to the console, BUT, I ALSO get the 404 message to the console too?
Is this the expected behavior? I am using the latest 2.5.4 express on 4.11 but have tried it on other versions of node with the same results.
I dont really like the fact that my 404 route gets called on every single request, I must be doing something wrong.
This is probably due to fact that browser trying to get also favicon for your page.
Just use express.favicon() creating your server:
express.createServer(
express.favicon()
);
You may also want to use logger to discover thing like this, it's really useful middleware.

Resources