NodeJS sessions, cookies and mysql - mysql

I'm trying to build an auth system and I have app.js
var express = require('express')
, MemoryStore = require('express').session.MemoryStore
, app = express();
app.use(express.cookieParser());
app.use(express.session({ secret: 'keyboard cat', store: new MemoryStore({ reapInterval: 60000 * 10 })}));
app.use(app.router);
and the route.index as
var express = require('express')
, mysql = require('mysql')
, crypto = require('crypto')
, app = module.exports = express();
app.get('/*',function(req,res){
var url = req.url.split('/');
if (url[1] == 'favicon.ico')
return;
if (!req.session.user) {
if (url.length == 4 && url[1] == 'login') {
var connection = mysql.createConnection({
host : 'localhost',
user : 'user',
password : 'pass',
});
var result = null;
connection.connect();
connection.query('use database');
var word = url[3];
var password = crypto.createHash('md5').update(word).digest("hex");
connection.query('SELECT id,level FROM users WHERE email = "'+url[2]+'" AND password = "'+password+'"', function(err, rows, fields) {
if (err) throw err;
for (i in rows) {
result = rows[i].level;
}
req.session.user = result;
});
connection.end();
}
}
console.log(req.session.user)
when I access http://mydomain.com/login/user/pass a first time it shows in the last console call but a second time access the cookie is clean

Why do you not just use Express's session handling? if you use the express command line tool as express --sessions it will create the project template with session support. From there you can copy the session lines into your current project. There more information in How do sessions work in Express.js with Node.js? (which this looks like it may be a duplicate of)
As for sanitizing your SQL, you seem to be using the library, which will santitize your inputs for your if you use parameterized queries (ie, ? placeholders).
Final thing, you are using Express wrong (no offence). Express's router will let you split alot of your routes (along with allowing you to configure the favicon. See Unable to Change Favicon with Express.js (second answer).
Using the '/*' route will just catch all GET requests, which greatly limits what the router can do for you.
(continued from comments; putting it here for code blocks)
Now that you have an app with session support, try these two routes:
app.get('/makesession', function (req, res) {
req.session.message = 'Hello world';
res.end('Created session with message : Hello world');
});
app.get('/getsession', function (req, res) {
if (typeof req.session.message == 'undefined') {
res.end('No session');
} else {
res.end('Session message: '+req.session.message);
}
});
If you navigate in your browser to /makesession, it will set a session message and notify you that it did. Now if you navigate to /getsession, it will send you back the session message if it exists, or else it will tell you that the session does not exist.

You need to save your cookie value in the response object:
res.cookie('session', 'user', result);
http://expressjs.com/api.html#res.cookie

Related

Angular 4 with nodejs and Mysql connectivity

I am new in angular and node js. I want to know how angular connect with node js with mysql server. Which simple return query result. Can anyone help me.
Angular is a fronend framework and nodejs can be used to implement a backend for a system. And you can use mysql as your DBMS.
You have to implement your backend and frontend separately. From backend you are exposing endpoints, routes, apis to the external applications.
And you can access those apis,routes from angular using HttpClient module. You can make Http requests using that.
Hope this helps
You may need to use some libraries to make a connection between angular frontend and backend with MySQL database.
You will need the express.js to handle the backend for the data request. Because you use the MySQL database, the database language would be different from any others such as MongoDB. The express provided database integration for the different databases.
You also need a body-parser as a middleware to parse the request body. This is a very important part of your project. The req is very complicated and this middleware can help to get the information which you need.
Here is a sample of how to use express connect mysql.
var express = require('express');
var query = require('./query')
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var app = express();
//Middleware for bodyparsing using both json and urlencoding
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
});
//login
app.post('/login',(req,res)=>{
var opts = req.body;
query(" SELECT *FROM `v_users` WHERE userAcount = ?",opts.userName).then((result)=>{
var response = result[0];
if(opts.password !== response.u_password){
return res.send({
errorCode:'404',
errorMsg:'password error'
})
}
//loginToken
var loginToken = response.userAcount + Math.random()*Math.pow(10,16)
res.send({
loginToken:loginToken
})
})
})
var server = app.listen(3000,()=>{
console.log('success')
})
Here is the query method:
(function() {
var mysql = require('mysql');
// var session = require('cookie-session');
var query = (sql,key) => {
var connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'root123',
database: 'm_users'
});
connection.connect()
var promise = new Promise((resolve,reject)=>{
connection.query(sql,[key], function(error, results, fields) {
if(error){
reject(error)
}else{
resolve(results);
}
});
connection.end();
});
return promise;
}
module.exports = query;
})()

Best practices for MySQL + Node/Express + Angular Stack

I am currently using MySQL for the db instead of the popular mongodb, since that is the case there isn't much documentation out there as far as architecture and getting set up. This is my current structure
client
-- angular files
routes
-- index.js
views
-- 404 page
app.js
I don't understand how I can implement controllers or models into this structure. I'm currently grabbing data from the db or sending it with the routes..I'm not sure what the added layer of controllers would do. Maybe this is a dumb question but I would just like to have a clear baseline so that my project will scale well. I feel like there should be way more to this than what I currently have.
index.js
const express = require('express');
const mysql = require('mysql');
const router = express.Router();
const db = mysql.createConnection({
host : 'localhost',
user : 'root',
password : 'password',
database : 'db'
});
// Connect
db.connect((err) => {
if(err){
throw err;
}
console.log('MySql Connected...');
});
// Select Data
router.get('/getData', (req, res) => {
let sql = 'SELECT * FROM data';
let query = db.query(sql, (err, results) => {
if(err) throw err;
console.log(results);
res.send(results)
});
});
module.exports = router;
app.js
const express = require('express');
const mysql = require('mysql');
const bodyParser = require('body-parser');
const path = require('path');
const cors = require('cors');
const compression = require('compression');
const helmet = require('helmet')
const expressSanitizer = require('express-sanitizer');
const index = require('./routes/index');
const app = express();
const port = 3000;
var corsOptions = {
origin: 'http://localhost:8100',
optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
}
// var logger = (req, res, next) => {
// console.log('logging...')
// next();
// }
//added security
app.use(helmet())
// //set logger
// app.use(logger)
//cors options
app.use(cors(corsOptions))
//body parser middleware
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: false}))
// Mount express-sanitizer here
app.use(expressSanitizer()); // this line follows bodyParser() instantiations
//set static path
app.use(express.static(path.join(__dirname, 'client')));
// set our default template engine to "ejs"
// which prevents the need for using file extensions
app.set('view engine', 'ejs');
//gzip compression
app.use(compression())
//set views for error and 404 pages
app.set('views', path.join(__dirname, 'views'));
app.use('/', index);
app.use('/fp/trips', trips);
app.listen(port, () => {
console.log('server started on port 3000')
})
When working on Node apps I tend to favor a scheme where controllers are (almost) services -- I think it works really well for small applications.
This is an example:
index.js
let app = express()
let users = require('./services/users')
app.get('/users/:id', async function(req, res, next) => {
try {
res.json(users.getByid(req.params.id))
} catch() {
next(err)
}
})
app.listen(8080)
services/users.js
let db = require('./db')
async function getById(id) {
let conn = await db.connect()
let user = conn.query('SELECT * FROM user WHERE id = ?', [id])
if (!user) {
throw new Error("404")
}
return user
}
module.exports = {getById}
services/db.js
let realDb = require('some-open-source-library-to-interact-with-db')
realDb.initialize(process.env.DB_CREDENTIALS) // pseudo-code here
module.exports = realDb
This though, won't work well when you're building large, complex apps -- I think you will require more structure in that case.
PS: I wouldn't suggest to build a large, complex app ever -- split it into smaller ones where patterns like the one I presented work nicely.
You can use Sequelize as ORM (Object Relational Mapper) for your MySQL DB to make your code more readable and to allow you to create better structure of your app. It also has support for PostgreSQL, MySQL, MariaDB, SQLite, and MSSQL.
There are samples out there how to integrate Sequelize with Express. I'm not sure if I'm allowed to post a github repository here but here it is:
https://github.com/jpotts18/mean-stack-relational
PS. I don't own this repository but this might help you somehow.

Angular 4 - display date from database

I need display data in table from MySql database, but I dont know how it do this.
I tried found something example or example application with source code, but I nothing found.
Maybe someone help me with this?
I tried with node.js express:
var mysql = require('mysql');
var https = require('https');
var con = mysql.createConnection({
host: "https://adress to database",
user: "user",
password: "password",
database: "db"
});
con.connect(function(err) {
if (err) throw err;
console.log("Connected!");
});
But i get error:
Error: getaddrinfo ENOTFOUND
here is a simple way to get data from mySQL and export it as json:
var http = require('http');
var mysql = require('mysql');
var bodyParser = require("body-parser");
var express = require('express');
var app = express();
var pool = mysql.createPool({
host: 'db location',
user: 'username od db',
password: 'something',
database: 'yourdatabase',
port:3306
});
// define rute
var apiRoutes = express.Router();
var port = 9000;
apiRoutes.get('/', function (req, res) {
res.json({ message: 'API works' });
});
apiRoutes.get('/data', function (req, res, next) {
pool.getConnection(function (err, connection) {
if (err) {
console.error("error hapened: " + err);
}
var query = "SELECT * FROM imena ORDER BY id ASC";
var table = ["imena"];
query = mysql.format(query, table);
connection.query(query, function (err, rows) {
connection.release();
if (err) {
return next(err);
} else {
res.json({
success: true,
list_users: rows
});
}
});
});
});
app.use('/api', apiRoutes);
// starting
app.listen(port);
console.log('API radi # port:' + ' ' + port);
But i still suggest that you start using noSQL databases like firebase because of they are simple and faster.
In order to show data from MySQL Database, you need to provide application interface(s) to Angular environment and only then Angular can use the data. There are few techniques in which you can design interfaces, REST is the most popular though.
First you need to understand that Angular is Front-End framework and it can only send requests to backend such as Node js, PHP etc.Thus, first you need to chose your backend. Node is popular with express js module, but if you still don't have mySQL set, go for firebase real time database. If you decide node js => express => mySQL check tutorial online.

Can't get and read GET request

I have a problem using Node.js. I am sending data via GET request to special script, which should read this data and write it in MySQL. Here is an example of GET request (very long):
http://demo.com/?&bssid=16~6D~57~7F~D8~AD&mac=60~01~94~2B~A8~85&rssi=0&hotspots_list=~~0_74~85~2A~39~77~48_-85~~~~1_78~8C~54~33~D8~3C_-91~~~
~2_64~6E~EA~0E~B3~26_-84~~~~3_76~85~2A~39~77~49_-87~~~~4_2C~33~7A~16~91~3B_-92~~~~5_54~BE~F7~6B~EE~43_-92~~~~6_98~DE~D0~AB~B8~64_-91~~~~7_14~DD~A9~1E
~F6~F8_-93~~~~8_64~6E~EA~0C~9A~3E_-84~~~~9_E8~DE~27~50~2A~12_-88~~~~10_84~C9~B2~0B~BA~C2_-81~~~~11_00~0F~94~BE~FC~44_-87~~~~12_56~BE~F7~6B~EE~44_-86~
~~~13_00~0E~8F~85~5F~73_-53~~~~14_0C~54~A5~A6~C1~1F_-87~~~~15_16~6D~57~7F~D8~AD_-78~~~~16_0E~54~A5~A6~C1~10_-92~~~~0_EC~1A~59~17~CF~5F_-91~~~~1_74~85
~2A~39~77~48_-92~~~~2_16~6D~57~7F~D8~AD_-77~~~~3_0C~54~A5~A6~C1~1F_-92~~~~4_0E~54~A5~A6~C1~10_-83~~~~5_84~C9~B2~0B~BA~C2_-82~~~~6_14~DD~A9~1E~F6~F8_-
92~~~~7_64~6E~EA~0C~9A~3E_-85~~~~8_E8~DE~27~50~2A~12_-93~~~~9_00~22~6B~56~2B~83_-92~~~~10_00~0E~8F~85~5F~73_-58~~~~11_00~0F~94~DB~DE~64_-91~~~~12_16~
DD~A9~1E~F6~F9_-92~~
I've done few experiments, and I found out, that it works fine in PHP, my code (only for output):
<?php
echo $_GET["bssid"]." ".$_GET["mac"]." ".$_GET["rssi"]." ".$_GET["hotspots_list"];
?>
But not in Node.js !This is my Node.js code:
var express = require("express");
var app = express();
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'host',
user : 'user',
password : 'pswd',
database : 'db'
});
var bssid, mac, rssi, hotspots_list;
const port = 3000;
const host = "0.0.0.0";
app.get('/', function (request, response) {
//Writing data to vars
bssid = request.query.bssid;
mac = request.query.mac;
rssi = request.query.rssi;
hotspots_list = request.query.hotspots_list;
//Sending request to MySQL server
connection.query(`INSERT INTO locations (mac, bssid_current, rssi_currnet, hotspots_list) VALUES ('${mac}','${bssid}','${rssi}','${hotspots_list}')`);
//Debugging line
console.log(`BSSID: ${bssid}`);
//Response
response.statusCode = 200;
response.setHeader('Content-Type', 'text/plain');
return response.send('Done');
});
app.listen(port, host, () => {
console.log(`Server running!`);
});
In your code, your route is /. And you are trying to access it via /server.js
Two solutions, either you add
app.get('/server.js', [...]) or you access it after removing server.js from your url.

How to properly use node-mysql?

I just started using node-mysql2 and I am confused how to use it properly. Examples:
(Implicitly established connection)
var express = require("express"),
app = express();
var mysql = require("mysql2");
var conn = mysql.createConnection({ ... });
app.VERB("/", function(req, res){
conn.query('SELECT 1+1 as test1', function(err, rows) {
// Show data to user...
// No .end() needed?
});
});
app.listen(8000);
second example:
var express = require("express"),
app = express();
var mysql = require("mysql2");
var conn = mysql.createConnection({ ... });
conn.connect(function(err){ ... }); // Is it right place to put it here? Or it has to go inside the callback below?
app.VERB("/", function(req, res){
conn.query("SELECT 1+1 as test1", function(err, rows){
// Show data to user...
conn.end(); // .end() necessary?
});
});
app.listen(8000);
Although I haven’t used node-mysql2, it is compatible with the original node-mysql module, so the same usage patterns apply.
The best way to use it is with connection pooling. That way, the MySQL client will create and destroy connections as needed. Your job is to call connection.release() when you no longer need a connection:
var express = require("express"),
app = express();
var mysql = require("mysql2");
var pool = mysql.createPool({ ... });
app.VERB("/", function(req, res){
pool.getConnection(function(err, conn) {
if (err) { /* handle the error and bail out */ }
conn.query('SELECT 1+1 as test1', function(err, rows) {
conn.release(); /* the connection is released back to the pool */
if (err) { /* handle the error */ }
else { /* show data to user */ }
});
});
});
app.listen(8000);
If your app runs “forever” (a web site for example) then you don’t need to call pool.end(). If you’re not using a connection pool, you don’t need to call connection.end() after each request. You wouldn’t want to: that would give you the overhead of establishing/tearing down the MySQL connection on every request!
If your app does not run “forever” (a command-line utility, for example), then call pool.end() or connection.end() just before you exit back to the command-line.