I need to redirect to login page if there any network issue or service down happen. I done a code which is redirect to login page. The problem is it redirect only the body. The layout is still there I want to show complete login page. Meaning I need to remove the layout. I have tried using window.location.href however I would like to use res.redirect('/');
> var isAuthenticated = function (req, res, next) {
var now = moment();
// logger.error("Tracing here", {"name":"routeshandler.js", "operation" : "isAuthenticated" });
// if user is authenticated in the session, call the next() to call the next request handler
// Passport adds this method to request object. A middleware is allowed to add properties to
// request and response objects
if (req.isAuthenticated()) {
if (req.user && global.users[req.user.userid]) {
global.users[req.user.userid].lastactive = now;
}
return next();
}
req.logout();
// if the user is not authenticated then redirect him to the login page
res.redirect('/');
res.end();
}
But it is load only the body. the layout is still there. How can I reload the complete page?
Related
Express js middleware is not working as expected. It is showing too many redirections.
When i remove the token or logout it shows in the browser that too many redirections
Middleware
const isAuthenticate = async (req, res, next) => {
const token = req.cookies.jwt;
if (token) {
jwt.verify(token, "thisisjwtsecret", async (err, token_decode) => {
if (!err) {
const u_id = token_decode._id;
const userData = await User.findOne({ _id: u_id });
req.user = userData;
req.isAuth = true;
next();
} else {
res.redirect("/user/login");
}
});
} else {
res.redirect("/user/login");
}
};
Route.js
// Auth Controller
const AuthController = require("../../controllers/auth/AuthController");
const { isAuthenticate } = require("../../middlewares/isAutheticated");
router.get("/user/login", isAuthenticate, AuthController.login);
router.post("/user/login", AuthController.checkLogin);
router.get("/user/register", isAuthenticate, AuthController.createUser);
router.post("/user/register", isAuthenticate, AuthController.storeUser);
module.exports = router;
LOgin function
// Showing Login Page to User
const login = (req, res) => {
return res.render("auth/login");
};
When i remove the token or logout it shows in the browser that too many redirections
Now that you've shown revised code for isAuthenticate(), the redirect loop is caused by the redirects in that code. Here's what happens:
Some route you have (any route) that uses isAuthenticate as middleware for the route detects that the user is not logged in. It then redirects to /user/login. That's fine up to that point. Then, the browser issues a new request for /user/login and that takes you to this route definition:
router.get("/user/login", isAuthenticate, AuthController.login);
But, that route definition again runs the isAuthenticate() middleware which redirects to /user/login and thus you have an infinite redirect loop.
Probably you just need to remove the isAuthenticate() check from this route. If the user is already going to the /user/login page, you don't need to check their authentication or redirect them. If you have a reason to want to know if they are authenticated or not, then you need a separate version that ONLY does the auth check and does not redirect and you can use that in the /user/login route definition.
Original answer before code was shown that did res.redirect().
So, this middleware you show sets req.isAuth to true or false and then calls next() to continue routing. All three code paths through that middleware just set req.isAuth and then call next(). Nowhere in this middleware does it do any redirect. So, if the core problem is too many redirections, that issue must be caused somewhere else by some other route/middleware that actually does a redirect, probably when it sees that req.isAuth is false since you said that the problem occurs when logged out or when the token is missing.
When redirecting, you have to make absolutely sure that when you redirect to a URL, there is ZERO chance (no code path of any kind) that the route handler for that URL will also redirect to that URL. That's how you get into a redirect loop.
Looking at the other routes you show, if the too many redirects issue is when redirecting to /user/login, then it seems likely the problem is in the authController.login() handler from this route:
router.get("/user/login", isAuthenticate, AuthController.login);
If the code for that route checks req.isAuth and redirects in any circumstances, then that would be an endless redirect loop.
If you need further advice, please provide the following information:
Which exact redirect URL is causing the problem of too many redirects? Is is /user/login?
Show us the code for the route that does that redirect because that's apparently where the fault is.
here is my router:
router.post('/login',
passport.authenticate('local'),
(req, res, next) => {
body('backurl').trim().escape();
let referrer = req.get('Referrer')
if (!req.user) {
return res.render('login', {
message: 'Unable to login, the password or the username are wrong',
backUrl: referrer
});
}
if (req.body.backurl == null || req.body.backurl == 'http://localhost:3000/signup' || req.body.backurl == 'http://localhost:3000/login') {
return res.redirect('/yourcourses');
}
return res.redirect(req.body.backurl);
}
);
When the user and the local authentication works it does work perfectly, however on fail I want to render the login page again with a message and a variable, however on failure the website simply makes an empty page with the word "unauthorized" on it without anything else, how do I fix it?
thanks!
When authentication in Passport fails, the next() function is not called, the middleware chain is stopped and a generic error is returned, that's why your code isn't executing.
The solution could be to create another route, for example '/loginfail', and moving in there the code that re-renders the 'login' page with the referrer and the error message.
Then, modify the call to passport.authenticate to include an options object, like this:
passport.authenticate('local', { failureRedirect: '/loginfail' });
So, when authentication fails, Passport calls the route you specified.
The idea:
I have a protected route "/me" and EACH TIME user tries to get there, he should enter his password (even if the user has been logged in already). If password is correct, then user goes to "/me" route.
The problem:
I use express. There is a middleware called "confirm-transaction" on "/me" route. And when user goes to "/me" route this middleware redirects user to "/confirm-transaction?redirect=/me" and user can see a field where he should enter his password.
And in this moment I don't know what to do, because if password is correct I try to redirect user to "/me" route (I get this route from "?redirect=/me" param), but the middleware again redirects him to "/confirm-transaction?redirect=/me". And user can never get to "/me" route.
The question is:
How can I solve this situation? I know that I should use "next()" if password is correct, but I can't do it as middleware does a redirect and I have no more "next()"
Here is some code:
const express = require('express');
const server = express();
const requestAuthorization = (req, res, next) => {
res.redirect(301, `/confirm-transaction?redirect=${req.originalUrl}`);
};
server.get('/me', requestAuthorization, (req, res) => {
res.status(200).send("this is /me route");
});
server.get('/confirm-transaction', (req, res) => {
res.status(200).sendFile("password.html");
// there is a form with field and button with POST method to '/confirm-transaction'
});
server.post('/confirm-transaction', (req, res) => {
if (req.query.password === 'testpassword') { // it is a fake password (for testing)
res.redirect(301, req.query.redirect);
}
res.redirect(301, `/confirm-transaction?redirect=${req.query.redirect}`);
});
/me blindly redirects to /confirm-transaction no matter what.
What you can do is to:
1. send user a token (or some sort) after successful authorization. Client stores it then the next request should have that token in the header.
2. Inside requestAuthorization() check if request header has valid token. If it does, dont redirect, otherwise, redirect.
Note: in you case, you might have to redirect with token in the header.
Note: that you have to store the token somewhere that has access to match the token with the user.
I quite don't understand the difference between these two:
app.get('*', function(req, res, next) {
next();
//ROUTE 1
});
app.get('*', function(req, res) {
res.redirect('/some');
//ROUTE 2
});
app.get('/some', function(req, res) {
res.send("success");
//ROUTE 3
});
When I try making request to ROUTE 1, I get response success but ROUTE 2 doesn't show this response. Why is that?
What I want to do is:
Every request should pass from ROUTE 1 and the control should be handled to a SPECIFIC route, which I would write in it ROUTE if-else statement (not like next(), which sends control to next MATCHING route).
For example:
app.get('*', function(req, res, next) {
if(x==y){
//call SPECIFIC route 3
} else {
// call SPECIFIC route 4 (another route)
//ROUTE 1
});
I tried to do it with redirect but it's not working.
Thank you.
EDIT:
Routes would be: /checkIfSession exists. I would use express-session to check if user's username exists or not in session.
If exists, I want to send control to if otherwise else.
Assume the requests are:
http://198.168.43.200:3000/checkIfSession
http://198.168.43.200:3000/some
(I will call only 1st request).
EDIT 2: I tried following but I don't get any response when I request:
app.use(function (req, res, next) {
if(2==2){
res.redirect("/session");
} else {
res.end("else");
}
});
app.get("/session", function(req, res){
res.write("session");
res.end();
});
app.get("/some", function(req, res){
res.write("some");
res.end();
});
Request: /some
I suppose if you want your routes to go through some kind of authentication first you can use middleware in your routes.
Below is sample code:
app.get('/some', checkSession, function(req, res) {
res.send("success");
});
// this is the middleware function
function checkSession(req, res, next) {
// do your checking here
if (x===y) {
next();
//continue users access to protected API
}
else {
res.redirect('/');
// redirect user to the default login page
}
}
In this above example there are 2 Cases
Case1:
x === y as from your given example I'am assuming users is logged in, so when the user is accessing /some section of your website he will receive Success from the server.
This is the use of your next() function i.e. it continues the execution of that api or sends the data whatever the user is requesting. Something similar to continue in your programming.
Case2:
x!==y now this will be the case where user is not authenticated or logged in and user is still trying to access the /some section of your website. In this case user will be redirected to login page of whatever you have designed for your website for him/her to re-enter his/her credentials.
Here your redirect function redirects the user without sending any data. Something similar to the break.
I have implemented Facebook login using passport in my application.
app.get('/index', ensureAuthenticated, function(req, res){
res.render('/', {});
});
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) { return next(); }
res.redirect('/')
}
In the front end I am using backbone for single page application, without a hash in url.
Backbone.history.start({ pushState: true });
When I enter /index in the url, it's redirecting to login page (which is perfect). But, when I enter /#index, indexView is loading.
What is the proper way to handle such conditions? I want to avoid having the user access any of my view, with or without hash in url, if they are not logged in.