Reputation: 813
I'm a relatively new web programmer and I'm currently working on my first major project. I'm using angular, express (on top of node), and the graph database neo4j. Right now I'm trying to determine the best (in terms of security and speed optimization) way to set up how the web app interacts with the database.
Right now I feel like I'm going into this somewhat blindly- What I'm looking for is a guide of best practices, security issues to take into account, and any other relevant advice or pitfalls to be aware of in setting up a web app backend.
To put this into a bit more concrete terms I'll give you an idea of how I'm setting up routes right now. The following are the routes setup in the app.js file.
//match database query functions
function dataQuery(req, res) {
var func = database[req.param('query')];
func(req, res);
}
//match database create functions
function dataCreate(req, res) {
var func = database[req.param('create')];
func(req, res);
}
//handle data queries
app.get('/query/:query', dataQuery);
//handle adding new content
app.post('/create/:create', dataCreate)
Essentially I have it set up so that I POST or GET to a url that just goes and executes a function. I'm essentially naming the function I want to run in the url: /query/theNameOfTheFunction. These functions then go and either build a cypher query (neo4j's query language) utilizing information in the request to interact with the database or handles things like adding user uploaded images.
Example: Creating Content (URL: /query/createContent)
exports.createContent = function (req, res) {
var content = JSON.parse(req.query.content);
var query = ("CREATE (n:Content {Title: {title}, URL: {url}, Description: {description}, Source: {source}, Links: {links}, Value: {valueStatement} })");
query = query.replace("{title}", "\"" + content.title + "\"");
query = query.replace("{url}", "\"" + content.url + "\"");
query = query.replace("{description}", "\"" + content.description + "\"");
query = query.replace("{source}", "\"" + content.source + "\"");
query = query.replace("{links}", "\"" + content.links + "\"");
query = query.replace("{valueStatement}", "\"" + content.valueStatement + "\"");
db.query(query, function (err, results) {
if (err) {res.send()};
res.send();
});
}
Here I've got a template for the query and just drop in user generated information using replace.
Example: Adding images to server (URL: /create/addImage)
exports.addImage = function (req,res) {
var url = req.query.url;
var fileName = req.query.fileName;
console.log(req.query);
request(url).pipe(fs.createWriteStream("./img/submittedContent/" + fileName));
res.send();
}
It seems that this approach is probably not very scalable but I'm not sure how to best organize the code on the server side.
One other specific example I would like to mention is the following case. The query itself is complicated and I've pushed creating it to the client side for now (the query looks for content related the terms that the user has selected and varies in length accordingly). The client sends the query that is created it is passed into the neo4j api. Obviously there are concerns here- if the user is able to define the query they could perform any action on the database (deleting everything or whatever). I'm not clear on how someone could go about doing this exactly, but it certainly seems feasible.
exports.getContent = function (req, res) {
var query = req.query.query;
//would checking for black/white list key terms be enough security? (remove, create, set, etc)
db.query(query, function (err, results) {
if (err) {throw err};
res.send(results);
});
}
Am I going about this stuff completely wrong headed? I've never gotten a formal introduction to server side scripting and am only going off of things I've read. I would like to do it the 'right way' but I need to know what that way is first...
Upvotes: 1
Views: 538
Reputation: 203409
Just some random pointers:
query.replace()
calls (see);Upvotes: 3