I'm new to web development. I'm writing an application with Node.js and want to use MySQL. I'm not sure how web technology works, but would people visiting my site be able to see my database credentials? According to the MySQL documentation (https://github.com/felixge/node-mysql) this is how to connect to a MySQL database.
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'me',
password : 'secret'
});
connection.connect();
connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
if (err) throw err;
console.log('The solution is: ', rows[0].solution);
});
connection.end();
No, they won't be able to see your code unless you run this on the client, which you shouldn't be able to or should, at all.
The example above runs on the backend and the query and data get displayed in the console, so it will only be accessible from the server and no clients connecting to it should be able see it, also you are not using anything to display a website ( based on the example above ) so you should not worry about it. If you want to, check out express or the http library for node.js.
After a while you should get the hang of it. Good luck!
People won't see your database credentials unless you publish the file in plain .js rather than executing it in node.js.
However, as an extra security measure, please prevent your database from connections outside the server, such as setting up a firewall to prevent port 3306 from outside connections, and use only 'localhost' users in your mysql database.
Related
So I figured the best way to learn is to try and fail over and over. I am building a webapp, at least trying to. I am curious how to go about using node to query my db. I am able to make a connection to the db with my single app.js file.
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'xxxxxxxx-us-east-1.rds.amazonaws.com',
port : '3306',
user : 'user',
password : 'password',
database : 'app'
});
connection.connect(function(err){
if(!err) {
console.log("Database is connected ... ");
} else {
console.log("Error connecting database ... ");
}
});
My problem, or lack of understand begins when I try to integrate this into my client-side js code. For instance say I wanted to trigger the db connection when a user uploads a photo.
var upload = s3.putObject({
Bucket: albumBucketName,
Key: photoKey,
Body: file,
ACL: "public-read",
});
var promise = upload.promise();
Can I include the app.js node file?
Sorry if this is a dumb question. I feel like I am missing some fundamental understanding of how to integrate the functionality of node with my current client side JS. Any help or further reading is appreciated--I am even curious about PHP solutions.
X
Server and client side code are separate. However you can create a Node module that harnesses the AWS and returns an appropriate response to the client after completed.
To do this, you need to create an endpoint that you post your data to from the client, then process with the same AWS modules only for Node. You also need to be able to access the connection instance from a different NodeJS module. This can be accomplished several ways. First, if the library that instantiates the connection tracks all of the connections, you should be able to require the library in a different module, then use the library's API to access one of the connections. Second, if you create only one instance of the connection and allow it to export, then you can import the module with that connection. Third, you can use something like a request/response pattern between the two modules, with the pattern instance declared globally.
If AWS Cognito is used with Node.js on the server-side, aren't the passwords, which are sent over, exposed without any form of encryption? AWS Cognito is intended to be used on the client-side, however I could get it work in my Node.js code, but I am wondering if a password is sent to the server, where it is processed now (instead of the client side), is it protected/encrypted in any ways now?
The AWS Cognito methods are called from the POST methods of my Node.js code.
E.g. the post method triggered by hitting the submit button on the registration page contains the code below. The password that the server sees through req.body.password seems unprotected to me. Is it?
userPool.signUp(req.body.username, req.body.password , attributeList, null, function(err, result){
if (err) {
console.log(err);
return;
}
unconfirmedUser = result.user;
res.redirect('/userVerification');
});
Of course it is.
Store your sensitive keys safely and you can run cognito very securely with Node.js.
In fact, AWS generally provide a place to store environment variables in their services consoles. So they even help you out a bit.
I'm using node.js and mongoDB. Right now, for my test app, the connection to the db is in the main node file, but I guess this is a wrong practice.
What I want/need: a secure way (i.e. not storing password on files users can access) to connect to the db just when needed.
For example: I want several admin pages (users, groups, etc..). Each page should connect to the db, find some data, and display it. It also have a form for adding a document to the db and a delete option.
I thought maybe to create some kind of a connection function - send it what you want to do (add, update, find, delete), to where (collection name) and whatever it needs. But I can't just include this function, because then it'll reveal the password to the db. So what can I do?
Thanks!
I'm going to answer your question bit by bit.
Right now, for my test app, the connection to the db is in the main node file
This is fine, though you might want to put it in a separate file for easier reuse. NodeJS is a continuesly running process, so in theory you could serve all of your HTTP responses using the same connection to the database. In practice you'd want to create a connection pool, but the Mongodb driver for NodeJS already does this automatically.
Each page should connect to the db, find some data, and display it.
When you issue a query on the MongoDB driver, it will automatically use a connection from its internal connection pool, as long as you gave it the credentials when your application was starting up.
What I want/need: a secure way (i.e. not storing password on files users can access) to connect to the db just when needed.
I would advice to keep your application configuration (any variables that depend on the environment in which the app is running) in a separate file which you don't commit to your VCS. A module like node-config can help a great deal with that.
The code you will end up with, using node-config, is something like:
config/default.json:
{
"mongo": null
}
This is the default configuration file which you commit.
config/local.json:
{
"mongo": "mongo://user:pass#host:port/db"
}
The local.json should be ignored by your VCS. It contains secret sauce.
connection.js:
var config = require('config');
var MongoClient = require('mongodb').MongoClient;
var cache;
module.exports = function(callback){
if(cache){
return callback(cache);
}
MongoClient.connect(config.get('mongo'), function(err, db){
if(err){
console.error(err.stack);
process.exit(1);
}
cache = db;
callback(db);
});
}
An incomplete example of how you might handle reusing the database connection. Note how the configuration is gotten using config.get(*). An actual implementation should have more robust error handling and prevent multiple connections from being made. Using Promises would make all that a lot easier.
index.js:
var connect = require('./connection');
connect(function(db){
db.find({whatever: true})
});
Now you can just require your database file anywhere you want, and reuse the same database connection, which handles pooling for you and you don't have your passwords hard-coded anywhere.
I see that a lot of people are using this module for using Node along with a mysql database: node-mysql
In everything I read people are storing their passwording and usernames in plain text in the js file. Javascript files can be read pretty easily, so isn't this a terrible thing?
Here is the connection code in the docs:
var connection = mysql.createConnection({
host : 'localhost',
user : 'me',
password : 'secret'
});
Am I missing a piece of the puzzle that disallows people from viewing your JS file on the server in plain text, password fully available?
It is not possible to store your password in a mysql connection with an encrytion. But you never should enter your password in a file which is send to the PC of a visitor. All files which contains login credentials or something like have to been saved on the server.
If you want to show some mysql contents to a visitor you can realise this with a small api which has to be programmed in js/php.
But if understand it right, you only want to run this javascript in a commandline with nodejs. Then you have no other solution as to store it without encryption and don't give the access to this server to someone else.
I'll typically have the app prompt you for the mysql password upon startup. This keeps the password out of a file on the server. You could also pass this as an argument to the script or set an environment variable.
Keeps the password off the filesystem but doesn't allow you to have the app autostart... it's a tradeoff
I know that most people say, "OH! It's not possible, use php" or whatever...
That would be a waste of my time. I don't want to hear that it's not possible.
I'm looking for anyway possible that I can access mysql using javascript. I don't care how much of a drawn out process it is or that it would take node.js.
Just give me a way to do it. Node.js or AJAX is something I'm willing to look into, but I'd rather just use javascript and nothing else.
I do know PHP, Node.js, and AJAX, so I'm not looking for an easy way out. I just want to find out how.
* edit *
I guess this would be more of what I am looking for:
Is there any other types of sql or some sort of database that is accessable by in browser javascript?
You should checkout https://mongolab.com/home They provide full access to a NoSQL database using JSON objects which are directly accessible with jQuery calls. I saw these guys at a Hackathon and ended up winning a prize! They are cool and will probably give you direct help if you click the support link.
Certainly possible. Web Application servers best suit that role, e.g. PHP, Cold Fusion, RubyOnRails, java(JSP), .net(ASP), etc.
You use javascript to send a request that the application server than uses to access the mysql server and... usually server up some of the results in a web page :)
To connect mysql using javascript, you can use the mysql package from npm.
npm i mysql
import mysql from "mysql";
var connection = mysql.createConnection({
host: "localhost",
user: "root",
password: "",
database: "social_media",
});
connection.connect();
const getUserById = (id) => {
connection.query(`SELECT * FROM users where id = ${id}`, function (err, results, fields) {
if (err) throw err;
console.log("The solution is: ", results);
});
};
getUserById(7);
connection.end();