URL does not change with res.render() - node.js

I need to send list of apps after login to ejs template engine from server with expressjs. For that purpose, I am using res.render(). Even though it renders the specified file, it does not change the url. What should I do to redirect along with data and make changes to url.
routes.js
const loginUser = requie('../Controller/LoginController');
router.post('/login', loginUser);
LoginController.js
const loginUser = (req, res) => {
/* login code */
res.render('apps/app-list', {
title: 'Application List',
isLoggedIn: true
});
};
After successfull login, it is rendering the contents of apps/app-list, but url is still users/login.

If you are trying to send data you should render a page, here is an example from a piece of my app:
app.get("/myfood", ensureAuthenticated, (req, res) => {
Food.find({}, (error, allfood) => {
if(error) {
console.log(error)
} else {
res.render("myfood", {food: allfood})
}
})
})
So I am sending all found food items with the get request. And you can send multiple objects. Just separate them with a comma.
As I said in a comment you can't do the same if you want to
res.redirect()
So, in my app, I wanted to send a flash message when the user signs up. Here:
newUser.save()
.then(user => {
req.flash("sucess_msg", "Thank you for registering.")
res.redirect("/login");
})
You can search a bit on YouTube on how to use req.flash() there are a couple great tutorials. I learned about it from Brad Traversy, passport node app.
That's about all I can give you. req.flash() is defined in a global variable
app.use((req, res, next) => {
res.locals.sucess_msg = req.flash("sucess_msg");
res.locals.error_msg = req.flash("error_msg");
res.locals.error = req.flash("error");
next();
});
Try to do the same and maybe go from there. Hope you will be a step closer

Related

redirect to req.headers.referer using passport

I have built a rest api where i use steam passport login. Seems like same as most other openid logins really. But my question is how can I redirect to the original req.headers.referer. Lets say I run with 5 different domains on this rest API. For example .no/.se/.com and another with one name. When the request comes in I want to redirect to the correct page where the original request came from.
Right now I am using a hard coded variable FRONTEND_URL but this wont work as I can only refer to one preset variable(.no) in this case. I tried to set a req.front=req.headers.referer in the /api/v1/auth/steam and the redirect to that in the /api/auth/steam/return but it didnt save it for some reason. The req.headers.referer in the /api/auth/steam/return returns undefined.
app.get(
"/api/v1/auth/steam",
passport.authenticate("steam", { failureRedirect: FRONTEND_URL + "/tos" }),
function (req, res) {
console.log(req.headers)
res.send(req.user);
}
);
app.get(
"/api/auth/steam/return",
passport.authenticate("steam", { failureRedirect: FRONTEND_URL + "/tos" }),
async function (req, res) {
const bot = await logon(req.user);
console.log(req.headers)
console.log(FRONTEND_URL)
req.session.steamuser = req.user;
req.session.steamuser.bot = bot;
res.redirect(FRONTEND_URL);
}
);

router express, a route return "Cannot GET", for no apparent reason

Here is a bug, that we could call stupid, that I had recently and that I just solved. I'm posting this here in case some people have the same problem.
const express = require("express");
const router = express.Router();
// define the home page route
router.get('/', function(req, res) {
res.send('agent home page');
});
// define the about route
router.get('/test', function(req, res) {
res.status(200).json({test:"test"});
});
router.get("/list ", function(req, res) {
try {
res.status(200).json({test:"test list"});
} catch (err) {
console.error(err);
res.status(500).json({ error: "Unexpected error : " + err });
}
});
the first two requests come from the express site and work very well.
https://expressjs.com/fr/guide/routing.html
The third one is the one I was planning to build.
In your opinion, why does the third request not work?
Well, it's the space between the quotation mark and the word list.
correction:
router.get("/list", function(req, res) {
In short, if you have a query that you just wrote or copied/pasted that doesn't work, check to see if there's an objectionable space, it could save you time.

Not able to redirect as a post request

I am trying to redirect the user with a post request from the home page after checking if their sessions exist.
This is my home controller file:-
const express = require('express');
const router = express.Router();
router.get('/', (req, res, next) => {
if (req.session["Data"] != undefined) {
res.redirect(307, '/Try');
}
else {res.render('home', {pageTitle: "Home"});}
});
module.exports = router;
But it is giving me error- Cannot GET /Try
This is what I'm using in my route file- router.post('/Try', try_controller.Try);
I am using res.redirect(307, '/Try') in another controller file of the same project and it's working. I can't figure out why it's not working here.
I don't think you can redirect a GET as a POST. If you own the /Try route, one option is to add a GET handler for that, then redirect will work.
Otherwise, in your GET route handler for \ you can create a new POST and return the results of that.
const request = require('request')
router.get('/', (req, res, next) => {
if (req.session["Data"] != undefined) {
//res.redirect(307, '/Try');
request.post('/Try', {}, function(err, response, body) {
if (err) return next(err)
return res.status(response.statusCode).send(body);
})
}
else {res.render('home', {pageTitle: "Home"});}
});
The example above an https://github.com/request/request though there are more modern ways of sending POST from express.
This isn't technically "redirecting", so you won't return 307 or 302.
I tried different things but in the end, I added an empty form in my home.pug file and submitted it using js.
JS code -
script.
let ssn = !{JSON.stringify(session)};
data = "Data"
if (ssn[data] != undefined) {document.getElementById('form-id').submit();}

How to redirect to variable link after authentication?

I'm working on a notes app , where people can keep their notes save (using express).
I want to add google authentication and for that I'm using passport.
My routs are -
/notes/:userId => for home page
http://localhost:8080/login/google/redirect => Authorized redirect URL
I'm also using a middleware isLoggedIn for checking if the user is loged in or not.
My middleware code -
module.exports.isLoggedIn = (req, res, next) => {
if(!req.user ){
req.flash('error', 'User must be signed-In');
return res.redirect('/login');
}
next();
}
In this I'm checking if the req have user property which passport atomatically adds while login using passport.autheticate() .
But now when i'm login using Google I need to use a fixed redirect URL. So how i redirect user to notes/:userId after authentication.
I tried using req.redirect in my redirect URL
router.get("/login/google/redirect", passport.authenticate('google', {failureRedirect: '/register'}),
async (req, res) => {
let userId = req.user._id;
res.redirect(`/notes/${userId}`);
});
but can't able to pass my middleware isLoggedIn.
How can I make this possible ?
Use isLoggedIn as /notes/:id route's middleware.
router.get("/notes/:id" , isLoggedIn, async (req, res) => {
// your logics code
});

Custom returnUrl on Node.js Passport's Google strategy

I'm using Express and Passport OpenID Google strategy and I would like to set returnURL on each auth request to be able to return to the page that initiated that auth.
The situation is that I have HTML5 slides application with Node.js backend (and with social stuff and editor and Portal and extensions... https://github.com/bubersson/humla) and I want be able to log in user on some slide (via slide menu...) but then I want him to get back to same slide easily.
So I would need something like this?
app.get('/auth/google', function(req,res) {
var cust = "http://localhost:1338/"+req.params.xxx;
passport.authenticate('google', returnURL:cust, function ...
}
I've read Passport's guide, but still don't know how to do that. I know this wouldn't be safe, but how else could I do it?
Or how can I make the application to return to the page from where the login has been initiated? Or is there a way to make OpenID authentication using AJAX (and still be able to use passport as well)?
I've figured this out for my apps Twitter authentication, I am sure that the GoogleStrategy is quite similar. Try a variant of this:
Assuming you have defined the route for the callback from the authentication service like so (from the passport guide):
app.get('/auth/twitter/callback',
passport.authenticate('twitter', {
successRedirect: authenticationRedirect(req, '/account')
, failureRedirect: '/'
})
);
Just change that block to this:
app.get('/auth/twitter/callback', function(req, res, next){
passport.authenticate('twitter', function(err, user, info){
// This is the default destination upon successful login.
var redirectUrl = '/account';
if (err) { return next(err); }
if (!user) { return res.redirect('/'); }
// If we have previously stored a redirectUrl, use that,
// otherwise, use the default.
if (req.session.redirectUrl) {
redirectUrl = req.session.redirectUrl;
req.session.redirectUrl = null;
}
req.logIn(user, function(err){
if (err) { return next(err); }
});
res.redirect(redirectUrl);
})(req, res, next);
});
Now, define your middleware for authenticated routes to store the original URL in the session like this:
ensureAuthenticated = function (req, res, next) {
if (req.isAuthenticated()) { return next(); }
// If the user is not authenticated, then we will start the authentication
// process. Before we do, let's store this originally requested URL in the
// session so we know where to return the user later.
req.session.redirectUrl = req.url;
// Resume normal authentication...
logger.info('User is not authenticated.');
req.flash("warn", "You must be logged-in to do that.");
res.redirect('/');
}
Works!
Wherever you have your login button, append the request's current URL as a
query parameter (adjust for whatever templating system you use):
<a href='/auth/google?redirect=<%= req.url %>'>Log In</a>
Then, add middleware to your GET /auth/google handler that stores this value in
req.session:
app.get('/auth/google', function(req, res, next) {
req.session.redirect = req.query.redirect;
next();
}, passport.authenticate('google'));
Finally, in your callback handler, redirect to the URL stored in the session:
app.get('/auth/google/callback', passport.authenticate('google',
failureRedirect: '/'
), function (req, res) {
res.redirect(req.session.redirect || '/');
delete req.session.redirect;
});
Try res.redirect('back'); in the callback for passport.authenticate
According to the author this isn't possible with OpenID strategies. We managed to update these dynamically by directly accessing the variables:
app.get('/auth/google', function(req, res, next) {
passport._strategies['google']._relyingParty.returnUrl = 'http://localhost:3000/test';
passport._strategies['google']._relyingParty.realm = 'http://localhost:3000';
passport.authenticate('google')(req, res, next);
});

Resources