On the front page of my app, the user can register an account and then login. It is expressed as a login and register button on the front page which then show the appropriate form when either are clicked.
I would like to replace the two buttons with a log out button if the user is already logged in but I need to inform the client of that first.
In my index.js, I am serving static html like so
app.use(express.static('public'));
I thought I could then do the following
app.get('/', function(req, res) {
// inform the client if req.user isn't null
});
but the callback is never called
I have found a solution.
In my index.js, I have this
app.get('/isloggedin', function(req, res) {
res.json({ loggedin: (req.user != null) });
});
And then I can just send a get request for /isloggedin and handle the result
$.get('/isloggedin', {}, function(data) {
if (!data.loggedin) {
// remove logged-in only elements
} else {
// remove logged-out only elements
}
});
Umm! i guess there would be a login/register form so there has to be two routes one with .get() and second one with .post():
app.get('/', function(req, res) {
// This is for navigation to the home page
}).post('/', function(req, res){
// inform the client here about the req.body.user
});
and i guess you have set up this:
app.use(bodyParser.urlencoded({extended:true})); // for "formurlencoded"
app.use(bodyParser.json()); // for "application/json"
if not then you have to load this module require('body-parser') first and require it only if you are using express 4.
Related
I'm having problems to redirect to another router after a Post. I see a 200 status code for the route I'm trying to navigate in the browser console and the whole page in the response payload. Through logs I see the redirect it's working, but the render is just not working.
I'm able to navigate to get to the page if I write the route manually in the browser, tho.
What am I missing?
I'll show you some code:
Server settings:
app.set('port', process.env.PORT || 9000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(require('./routes'));
app.use(express.static(path.join(basedir, 'public')));
Routes file:
router.get('/', (req, res) => {
res.render('login');
});
router.post('/login', (req, res) => {
res.redirect('/index');
})
router.get('/index', (req, res) => {
res.render('main-page');
})
PD: Yes...I'm totally new in Node.
From what you say, it sounds like you are sending an AJAX request. This means the response is delivered to your JavaScript code, it's not a navigation. So, essentially the redirect "works", as it redirects your AJAX request and returns the redirected page content.
If you were to submit a form via the browser (just using a basic <form> element), you would see a navigation.
In order for a navigation to occur after an AJAX request, you should not use res.redirect but instead return some JSON with the page you want to redirect to (e.g. res.send({ redirectTo: '/index' }) - the naming is your choice), and then check for the redirectTo parameter in your client-side code when it gets the response and navigate there manually using location.assign.
Example:
Server code:
router.post('/login', (req, res) => {
res.send({ redirectTo: '/index' })
})
Client code:
const result = await fetch('/login', { method: 'POST' })
const { redirectTo } = await result.json()
if (redirectTo) {
location.assign(redirectTo)
}
Alternatively, if the redirection target is static, you don't need any redirectTo value and can instead hardcode the target in the client-side code.
In case you want to allow both a form submit or an AJAX request (maybe you do progressive enhancement and your page is designed to work without JavaScript as well), then you can check the Accept header and see if HTML is accepted (req.accepts("html")), and if it is, you return a redirect, otherwise you return JSON. Similarly, in case of an error, you could conditionally render an error page or return JSON with an error message that your client-side code knows how to handle.
I am building a crud application using react and node , so i need to check for every request whether the cookie is present or not.
app.all("*", (req,res) => {
// cookie doesn't exist redirect to login
if(cookieExist(req.headers.cookie)){
// how to pass to the next layer ? load the routes below code etc..
next();
}else{
res.redirect("/login")
}
})
const routes = require("./routes/route");
app.use(bodyParser.json());
app.use(cors());
app.use("/apiServices", apiRoutes)
what i am missing here, getting next() as not defined.
Define next as argument
app.all("*", (req,res, next) => {
// cookie doesn't exist redirect to login
if(cookieExist(req.headers.cookie)){
// how to pass to the next layer ? load the routes below code etc..
next();
}else{
res.redirect("/login")
}
})
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'm using Node and Express for the first time to make a simple website that conducts CRUD operations on a database. When I issue my put request I can't get the page to redirect to '/index' and I've run debugger for express and haven't seen anything abnormal, the page simply doesn't change. Any thoughts? Here's the code in server.js
app.set('view engine', 'ejs')
app.all('/', function(req,res){
var cursor = db.collection('jobs').find().toArray(function(err, results) {
res.render('index.ejs', {jobs: results})
})
})
app.get('/index',function (req, res) {
res.sendFile(__dirname + '/index.html');
})
app.get('/view',function (req, res) {
var cursor = db.collection('jobs').find().toArray(function(err, results) {
res.render('index.ejs', {jobs: results})
})
})
app.post('/jobs', function(req, res) {
db.collection('jobs').save(req.body,function(err, result){
if (err) return console.log(err)
console.log('saved to database');
res.redirect('/view');
})
})
app.put('/view', function(req, res) {
res.redirect(303, '/index');
})
An HTTP redirect just tells the client to get the data it asked for from somewhere else. It doesn't tell it to treat it any differently.
If you make an Ajax request and get a redirect response, then the browser will follow that redirect silently and return the contents of the new URL to your JavaScript.
The browser won't see the redirect and decide to load a new page in the viewport instead of presenting the data to your JavaScript.
If you want to load a new page after making your PUT request, then you need to wait for the response to come in and then (for example) assign a new value to window.location.href.
More specifically, I have an auth system that uses passportjs and req.user is defined if the user is authenticated.
Right now my website only has about 5 pages, but it's growing, and at the top of every route, I check if req.user exists and I pass a true or false variable to the rendered template, and the template renders accordingly.
I messed around with things such as app.get("*") but I didn't end up finding anything good.
How could I check if req.user (or anything else that could exist within req...) exists -- when a user goes to any page of my website, without repeting code?
Progress:
Using this code in app.js:
app.use(function (req, res, next) {
// Using req.locals.isAuthenticated would be better, as it's automatically passed to every rendered templates.
req.context = {};
req.context.isLoggedIn = req.isAuthenticated();
// req.locals.isAuthenticated = req.isAuthenticated();
next();
});
app.use('/dashboard', dashboard);
and this in the routes/dashboard route:
router.get('/', function (req, res) {
res.render('dashboard', { isLoggedIn: req.context.isLoggedIn });
});
Works - I can then see if the user is logged in by doing for example {{ isLoggedIn }}.
However when I uncomment the req.locals line in the first code snippet, I get a 500 error.
Two things to note:
Usually when your application needs to do something for a bunch of different pages, you want to setup a middleware function via app.use
Express has a res.locals variable whose properties will be included in any rendered template
With the above points in mind, you can construct something like the following:
app.use(function(res, req, next) {
res.locals.isAuthenticated = typeof(req.user) !== 'undefined';
next();
});
You then supply your additional template variables when your routes call res.render. For example:
app.get('/about', function(res, req) {
res.render('about', { 'testValue': 14} );
});
Your template will have access to both isAuthenticated and testValue.
I recommend you put some middleware in place before your route handlers but after passport's.
app.use(function(req, res, next) {
// Create a `context` object for use in any view.
// This allows the context to grow without impacting too much.
req.context = {};
// Assign your flag for authenticated.
req.context.isAuthenticated = typeof req.user !== 'undefined';
// Let the next middleware function perform it's processing.
next();
});
Then you can render each view with the context.
app.use('/', function(req, res) {
res.render('index', req.context); // Context is passed to view for usage.
});
This is all untested code.
You can do it as is already mentioned here ,but in this case you are going to check completely every request. Maybe you have got / you are going to have some pages that don't require any authentification and in this case you have to make some statement that will skip auth for that particular page or you can use something like this:
function checkUser(req, res, next) {
req.userAuth = (req.user !== undefined);
next();
}
app.post("settings", checkUser, doSomething);
app.post("administration", checkUser, doSomething);
app.post("index", doSomething); // Doesn't require any authentification
Or you can straight a way redirect a user
function checkUser(req, res, next) {
if (req.user === undefined) {
res.redirect("/login"); // res.render
}
else {
next();
}
}