I am new to Express and writing an application in node js. I am having problem in using the same parameters. My code is:
app.get('/signin', function (req, res) {
renderView(req, res, 'signin.jade');
});
app.get('/config', function (req, res) {
addOrUpdateGroupConfig(req.query.group_name, req.query.webhook_url);
renderView(req, res, 'config.jade');
});
app.post('/config', function (req, res) {
..
}
function renderView(req, res, view, locals) {
if (locals === undefined) {
locals = {};
}
res.render(view, locals);
}
The sign in jade redirects to app.get(/config) and i am getting webhook_url and group_name. Now I am rendering a config jade page which has form post, after submit the control comes to app.post(/config) now the problem is i want the webhook_url and group_name here to store in database. SO how to pass those values in a good way ?
If the webhook_url and group_name values can't be put into the web page for security reasons, then the usual solution would be to create a session object and store it for that specific user in their session. Then, on the POST, you could get it out of that user's session. The express-session module is available to help you create a session object for each user. This is breaking with the usual stateless design of web pages so there'd have to be a really good reason to go this way.
Otherwise, the value should probably just be inserted into the form in a hidden field (by your renderer) so that when the POST happens, the value will be sent back with the form and you'll have everything you need in the POST data. That keeps your system entirely stateless which is good for a lot of reasons (simplicity, scalability, reliability, etc...).
Related
In index.js I am rendering page with global variables.
router.get('/index', function(req, res, next) {
res.render('index', { title: 'RLH',
countNumber: countNumber,
countReleased: countReleased,
countOpen: countOpen
});
in the same index.js I also have:
router.post('/index', function(req, res, next) {
datatamper = req.body;
countSev();
countTickets();
countTime();
});
On port 3000 I am listening for data, once I get it I am making some calculation and then the page is ready to be opened with global variables.
Clearly this is working just fine to open the page and all data will be here
On the page I am presenting data like that:
<p> <b> Tickets</b>: <span>{{countNumber}}</span></p>
Yet I would like to update just the data on the website by itself after every post(not refreshing the whole page).
Data by post is coming every minute, yet that might change.
You need to implement either some form of longpolling, where your javascript frontend sends requests to the api every so often to check for updates, and then adds them to the page, or use a technology like websockets to get the data as it's updated.
I'm new to authentication with websites, and I've been doing a lot of reading on the different kinds of user authentication (for example session vs token authentication) you can use. However, a lot of it seems more than what I need, and I'm not sure which ones will be suitable for my cause.
My idea is to generate temporary user accounts and passwords that will expire after the first use. I want this integrated with my website, so they have one chance to view restricted pages, after which they will not allowed access to those parts again (unless provided with new credentials).
Any direction in the right step will be appreciated.
Update: I'm using Javascript(Node) as my server side language
Session-based authentication is actually incredibly lightweight if you're using a Node backend, due to most (if not all) webserver libraries supporting "middleware", which modify requests before they hit your route functions. The Express-compatable middleware client-sessions is fantastic for this, and I used it previously in a project with great success. It adds a cookie on the first request a user makes to your site which identifies them, and if at some point they log in, you can flag that session as authenticated, store session information, and other data related to them specifically.
Assuming you want both login & logout, the simplest way would to be to use POSTs over HTTPS to login & logout routes. Inside of the resolution for the login route, you would simply "mark for deletion" inside whatever database you're working with.
An example might look like this:
var app = express();
function authenticate(user, pw){
//do your application specific login verification here
}
function deleteAccount(user){
//do your application specific user removal here
}
app.use(require("express-session")({
secret : "YOUR-SECRET-KEY-HERE"
cookieName : "Session"
//any other desired config options go here
})
app.post("/login", function(req, res){
var user = req.body.user;
var pw = req.body.pw;
req.Session.isAuthenticated = authenticate(user, pw)
if(req.Session.isAuthenticated){
markForDeletion(user, pw);
}
res.write("logged in as: " + user);
res.end();
});
app.post("/logout", function(req, res){
deleteAccount(req.Session.username);
req.Session.username = "";
req.Session.isAuthenticated = false;
res.write("logged out!");
res.end();
});
I use express.js, mongodb, ejs. In the navbar, there's an email icon and will display the count of new emails.
<%=newEmailCount%>
Then I need to add this newEmailCount to every route.
Emails.count({userId: userId, new: true})
my question is in express.js, how can I add a global function that can be executed by every route?
If you want to get the count for every GET requests then you can use following approach
router.get('*', function(req, res, next) {
res.locals.newEmailCount = Emails.count({userId: userId, new: true})
next();
})
You need to make sure this is always executed by placing it above all the other routes.
You can then pass res.locals.newEmailCount to your render function which renders HTML file for matched route.
This will work also for application instance level routes handling if that's what you're using.
I want to completely dissociate my client app from Parse server, to ease the switch to other Baas/custom backend in the future. As such, all client request will point to a node.js server who will make the request to Parse on behalf of the user.
Client <--> Node.js Server <--> Parse Server
As such, I need the node.js server to be able to switch between users so I can keep the context of their authentification.
I know how to authentificate, then keep the sessionToken of the user, and I ve seen during my research than the "accepted" solution to this problem was to call Parse.User.disableUnsafeCurrentUser, then using Parse.User.become() to switch the current user to the one making a request.
But that feels hackish, and I m pretty sure it will, sooner or later, lead to a race condition where the current user is switched before the request is made to Parse.
Another solution I found was to not care about Parse.User, and use the masterKey to save everything by the server, but that would make the server responsible of the ACL.
Is there a way to make request from different user other than thoses two?
Any request to the backend (query.find(), object.save(), etc) takes an optional options parameter as the final argument. This lets you specify extra permissions levels, such as forcing the master key or using a specific session token.
If you have the session token, your server code can make a request on behalf of that user, preserving ACL permissions.
Let's assume you have a table of Item objects, where we rely on ACLs to ensure that a user can only retrieve his own Items. The following code would use an explicit session token and only return the Items the user can see:
// fetch items visible to the user associate with `token`
fetchItems(token) {
new Parse.Query('Item')
.find({ sessionToken: token })
.then((results) => {
// do something with the items
});
}
become() was really designed for the Parse Cloud Code environment, where each request lives in a sandbox, and you can rely on a global current user for each request. It doesn't really make sense in a Node.js app, and we'll probably deprecate it.
I recently wrote a NodeJS application and had the same problem. I found that the combination of Parse.User.disableUnsafeCurrentUser and Parse.User.become() was not only hackish, but also caused several other problems I wasn't able to anticipate.
So here's what I did: I used
Parse.Cloud.useMasterKey(); and then loaded the current user by session ID as if it was a regular user object. It looked something like this:
module.exports = function(req, res, next) {
var Parse = req.app.locals.parse, query;
res.locals.parse = Parse;
if (req.session.userid === undefined) {
res.locals.user = undefined;
return next();
}
Parse.Cloud.useMasterKey();
query = new Parse.Query(Parse.User);
query.equalTo("objectId", req.session.userid);
query.first().then(function(result) {
res.locals.user = result;
return next();
}, function(err) {
res.locals.user = undefined;
console.error("error recovering user " + req.session.userid);
return next();
});
};
This code can obviously be optimized, but you can see the general idea. Upside: It works! Downside: No more use of Parse.User.current(), and the need to take special care in the backend that no conditions occur where someone overwrites data without permission.
So I'm doing a web page with Node.js and Express framework. I already have registration and login (I'm holding users id in a session). Next step is to render different page whenever a user is authenticated.
Some of those pages require a User object which is just a mapping of a user from my db. So whenever an authenticated request comes I need to retrieve the user from my db. But writing this code every time seems to be a bad way to do this. So here's the question: is it possible (and if it, then how?) to do, say preresponse, so I can automaticaly retrieve User object whenever I know that the user is authenticated and THEN do the main response?
Middleware is what you are referring to. Middleware is just a function that gets called sequentially when the route is triggered. So to have a loadUser function:
function loadUser(req, res, next) {
// You would fetch your user from the db
var user = users[req.params.id];
if (user) {
req.user = user;
next();
} else {
next(new Error('Failed to load user ' + req.params.id));
}
}
app.get('/user/:id', loadUser, function(req, res){
res.send('Viewing user ' + req.user.name);
});
You can define as many middleware functions as your need. Just be sure to call next() at the end to pass the route handling on to the next function.
This EXACT example is covered in the express.js route middleware docs. Go read it and you'll see the pattern of using middleware to factor out common functionality that you need at many route paths in your app.