I am stucked with one problem. As you can guess from title , problem is that i am making redirect loop . Simple situation but as a beginner i couldn't solve it . I will provide my code for you to see the problem.
So this is my express routers `
const passport = require('passport');
module.exports = (app) => {
app.get('/auth/eventbrite',
passport.authenticate('eventbrite', {}));
app.get('/auth/eventbrite/callback',
passport.authenticate('eventbrite', { failureRedirect: '/' }),
(req, res) => {
if (!req.user) {
throw new Error('user null');
}
res.redirect('/dashboard');
});
app.get('/api/logout', (req, res) => {
req.session = null;
req.logout();
res.redirect('/');
});
app.get('/api/current_user', (req, res) => {
res.send(req.user);
});
app.get('/dashboard', (req, res) => {
console.log(req.user, 'user');
if (!req.user) {
res.redirect('/');
} else {
res.redirect('/dashboard');
}
});
};
You can notice that i redirect user to /dashboard both in passport authentication and for get requests . My goal is to prevent user to come to dashboard if he/she is not authenticated .
If the user is logged in and is redirected to the dashboard, the dashboard redirects him again to the dashboard. This creates an endless loop. Instead, if the user is logged in, the dashboard route should respond. Most probably you want to send him the dashboard html page.
Related
I am using a middleware to check if a user is logged in to see certain pages which I've declared in a separate file from the route that I use to login. The middleware adds req.originalUrl to the req.session.returnTo field. I am using passport.authenticate in my login route to serialize a user onto the session but when it does so it takes away the req.returnTo field somehow ? I don't understand why.
middleware I'm using:
module.exports.isLoggedIn = (req, res, next) => {
if(!req.isAuthenticated()){
req.session.returnTo = req.originalUrl;
req.flash('error', 'Must be Signed in first');
res.redirect('/login');
}
else{
next();
}
}
This req.returnTo field does not show up when I try to use it in the login route:-
router.post('/login', passport.authenticate('local', { failureFlash: true, failureRedirect: '/login' }), (req, res) => {
req.flash('success', 'Welcome back !');
const redirectUrl = req.session.returnTo || '/campgrounds';
res.redirect(redirectUrl);
})
redirectUrl value is null
Try by saving session data as bellow
module.exports.isLoggedIn = (req, res, next) => {
if(!req.isAuthenticated()){
req.session.save(function(err) {
// session saved
req.session.returnTo = req.originalUrl;
})
req.flash('error', 'Must be Signed in first');
res.redirect('/login');
}
else{
next();
}
}
I'm building/learning a web-app with React and Express. All of the routes and redirects work but URL won't change and my props won't pass until i manually go to the URL.
For example;
After a successful login (local passport with MongoDB), it renders main page but it's empty since i don't get any data (user id or email etc..) but if enter URL manually or press home button on nav-bar, it works or if i logout it logouts but URL stays at /logout instead of /login. Example code below:
server.js
...
server.use((req, res, next) => {
res.locals.success_msg = req.flash("success_msg");
res.locals.error_msg = req.flash("error_msg");
res.locals.error = req.flash("error");
res.locals.messages = req.flash();
res.locals.user = req.user;
next();
});
server.get("/index", ensureAuthenticated, (req, res) => {
const msg = {name: req.user.name, email: req.user.email};
return app.render(req, res, "/index", msg);
});
server.post("/login", (req, res, next) => {
passport.authenticate("local", function(err, user, info) {
if (err) {
return next(err);
} else if (!user) {
req.flash("error_msg", info.message);
return app.render(req, res, "/login", req.flash());
} else {
req.logIn(user, function(err) {
if (err) {
return next(err);
}
req.user = user.name;
return app.render(req, res, "/index", user.name);
});
}
})(req, res, next);
});
server.get("/logout", (req, res) => {
req.logOut();
req.flash("success_msg", "done!");
return app.render(req, res, "/login", req.flash());
});
server.get("*", ensureAuthenticated, (req, res) => {
return handle(req, res);
});
I think that what you meant by return app.render(req, res, "/index", user.name); on your login method, is actually a redirect.
What render does is take the file and the data you give it and then send it back to the browser as a response.
However, what you're trying to do is have the user go to a different URL if the login process is successful, that can be accomplished by doing the following:
res.redirect('/index')
This will make the server go to your index route, which in turn executes all the code required for your user data to be loaded!
You can learn more about redirect and render by looking at the express docs.
My site www.exampartner.in runs on an EC2 instance using NodeJS connected to a domain I bought on bigrock.in. To use SSL I migrated to CloudFlare however ever since I migrated to CloudFlare my site is having issues. The main issue is the invalid redirect error I faced on the javascript, logo and ham pic after setting https redirect as a page rule. I then disabled it and tried to load these resources over HTTP but it still failed. Now I've disabled the SSL as well and the page seems to be working. I've attached screenshot for reference. Please Help. Thank You.
Here's my routes.js:
var express = require('express');
var router = express.Router();
var passport = require('passport');
router.get('/login', function (req, res, next) {
res.render('login', { message: req.flash('loginMessage'), user: req.user });
});
router.get('/', function (req, res) {
res.render('mainpage', { user: req.user });
});
router.get('/signup', function (req, res, next) {
res.render('signup', { message: req.flash('signupMessage'), user: req.user });
});
// process the login form
router.post('/login', passport.authenticate('local-login', {
successRedirect: '/profile', // redirect to the secure profile section
failureRedirect: '/login', // redirect back to the signup page if there is an error
failureFlash: true // allow flash messages
}));
// app.post('/signup', do all our passport stuff here);
router.post('/signup', passport.authenticate('local-signup', {
successRedirect: '/profile', // redirect to the secure profile section
failureRedirect: '/signup', // redirect back to the signup page if there is an error
failureFlash: true // allow flash messages
}));
// =====================================
// PROFILE SECTION =====================
// =====================================
// we will want this protected so you have to be logged in to visit
// we will use route middleware to verify this (the isLoggedIn function)
router.get('/profile', isLoggedIn, function (req, res) {
res.render('profile', {
user: req.user // get the user out of session and pass to template
});
});
// =====================================
// LOGOUT ==============================
// =====================================
router.get('/logout', function (req, res) {
req.logout();
res.redirect('/');
});
// };
// route middleware to make sure a user is logged in
function isLoggedIn(req, res, next) {
// if user is authenticated in the session, carry on
if (req.isAuthenticated())
return next();
// if they aren't logged redirect them to the home page
res.redirect('/');
}
router.post('/login', passport.authenticate('local-login', {
successRedirect: '/profile', // redirect to the secure profile section
failureRedirect: '/login', // redirect back to the signup page if there is an error
failureFlash: true // allow flash messages
}));
router.get('/bitsat', function (req, res) {
res.render('bitsat', { user: req.user });
})
router.get('/aieee', function (req, res) {
res.render('aieee', { user: req.user });
})
router.get('/ip', function (req, res) {
res.render('ip', { user: req.user });
})
router.get('/jeemain', function (req, res) {
res.render('jeemain', { user: req.user });
})
router.get('/jeeadvanced', function (req, res) {
res.render('jeeadvanced', { user: req.user });
})
router.get('/jeemain/:year', function (req, res) {
res.render(__dirname + '/views/jee_main/' + req.params.year, { user: req.user });
});
router.get('/jeemain/:year/:paper', function (req, res) {
var filename = req.params.paper.substr(0, 2) + 'April' + req.params.year
var mor = req.params.paper.indexOf('Morning')
var eve = req.params.paper.indexOf('Evening')
if (mor !== -1) {
filename = filename + req.params.paper.substr(mor, req.params.paper.length)
}
if (eve !== -1) {
filename = filename + req.params.paper.substr(eve, req.params.paper.length);
}
res.download(__dirname + '/downloads/jee_main/' + req.params.year + '/' + filename + '.pdf')
});
router.get('/bitsat/:op', function (req, res) {
res.render(__dirname + '/views/bitsat/' + req.params.op, { user: req.user });
});
router.get('/bitsat/:op/:year', function (req, res) {
res.download(__dirname + '/downloads/bitsat/' + req.params.op + '/' + req.params.year + '.pdf')
});
module.exports = router;
Edit: In order to use Cloudflare's strict SSL, you need to install an SSL certificate on your server. Lets Encrypt provides free SSL certificates that have to be renewed every 90 days. If the process seems difficult, you can use Zero SSL which makes it easy to get a certificate from lets encrypt, as well as to update existing certificate.
You have to set up express to handle https request/response. The Node.js app needs ssl certificate and key.
const express = require('express')
const fs = require('fs')
const https = require('https')
const app = express()
https.createServer({
key: fs.readFileSync('server.key'),
cert: fs.readFileSync('server.cert')
}, app)
.listen(process.env.PORT || 3000, function () {
console.log('"App Listening at port:" + port')
})
My app is on express, mongoDB. I add authorization by session. Don't work logout. There is the link on a page (this is pug):
a(href="/logout") logout
It's handler:
app.get('/logout', function (req, res, next) {
if (req.session) {
// delete session object
req.session.destroy(function (err) {
if (err) {
return next(err);
} else {
return res.redirect('/');
}
});
}
});
When clicked, it displays this and redirect does not occur. If you delete everything except redirect, then redirect will work. But I need to delete the authorization session.
try something like this
app.get('/logout', function (req, res, next) {
// If the user is loggedin
if (req.session.loggedin) {
req.session.loggedin = false;
res.redirect('/');
}else{
// Not logged in
res.redirect('/');
}
});
If you are using passportjs, you need to call the req.logout() to terminate a login session. See documentation here
Currently using node.js, express & passport.js to create a custom website/application.
Having followed several guides, I have a functioning login/logout system with authentication. However, should a user revisit and their session is still active, it doesn't redirect them to the 'dashboard'.
Current root route:
/* GET login page. */
router.get('/',function(req, res) {
// Display the Login page with any flash message, if any
res.render('index', { message: req.flash('message') });
});
I am making use of the isAuthenticated function, as below:
var isAuthenticated = function (req, res, next) {
if (req.isAuthenticated())
return next();
res.redirect('/');
}
How do I get it to automatically redirect users with an existing session? Any pointers most welcome!
Ok, I figured it out. In the / route, I queried whether req.user was set.
/* GET login page. */
router.get('/',function(req, res) {
if(req.user){
res.redirect("/dashboard");
}else{
// Display the Login page with any flash message, if any
res.render('index', { message: req.flash('message') });
}
});
You can attach a middleware with "/" endpoint something like this.
router.get('/', sessionValidate, function(req, res, next) {
res.render('login');
});
Where sessionValidate looks something like this :
function sessionValidate(req,res,next){
console.log(req.user,"i am here");
users.findById(req.user,function(err, user) {
if(user!=null){
req.session.user = user;
res.locals.user=user;
res.redirect("/home")
}
else {
next();
}
});
}