I am new in node.js
I am trying to make a login and registration system using express.js, vanilla JS, CSS, HTML, and MySql.
below is code that handles routing as well as parses HTTP Post requests made by the client which consists of username and password. username and password are stored inside fields.username and fields.password
functions userRegistration(...) and userLogin(...) are defined inside db.js ( shown at the end ); they are exported from db.js and are imported in users.js
users.js
router.post('/register', (req, res, next) => {
const form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
var userInfoArray = [fields.username, fields.password]
db.userRegistration(userInfoArray)
})
});
router.post('/login', (req, res, next) => {
const form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
var userInfoArray = [fields.username, fields.password]
db.userLogin(userInfoArray)
})
});
I have created userinfo table to store usernames and passwords.
As shown below I am getting username and password by HTTP post method. Which I am parsing using
formidable module which gives me fields.username and fields.password values.
I am using query(...) method to query database providing actual SQL as string named registrationQueryString (to insert an entry into table) and loginQueryString(to find whether provided username and password are in the database or not)
db.js
var username, password;
var userInfoArray = [username, password]
const registrationQueryString = "INSERT INTO (username, password) userinfo VALUES ( ?, ? )"
const loginQueryString = "SELECT (username, password) FROM userinfo WHERE EXISTS (SELECT (username, password) FROM userinfo WHERE username = (?) AND password = (?))"
function userRegistration (userInfoArray){
dbConnection.query( registrationQueryString, userInfoArray, function(err, results, fields) {
if (err) throw err
console.log(results)
})
}
function userLogin (userInfoArray){
dbConnection.query( loginQueryString, userInfoArray, function(err, results, fields) {
if (err) throw err
console.log(results)
})
}
It is giving me an error
"wer" is random value I provided as username and password
Error: ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(username, password) userinfo VALUES ( 'wer', 'wer' )' at line 1
at Query.Sequence._packetToError (F:\dr.server\node_modules\mysql\lib\protocol\sequences\Sequence.js:47:14)
at Query.ErrorPacket (F:\dr.server\node_modules\mysql\lib\protocol\sequences\Query.js:79:18)
at Protocol._parsePacket (F:\dr.server\node_modules\mysql\lib\protocol\Protocol.js:291:23)
at Parser._parsePacket (F:\dr.server\node_modules\mysql\lib\protocol\Parser.js:433:10)
at Parser.write (F:\dr.server\node_modules\mysql\lib\protocol\Parser.js:43:10)
at Protocol.write (F:\dr.server\node_modules\mysql\lib\protocol\Protocol.js:38:16)
at Socket.<anonymous> (F:\dr.server\node_modules\mysql\lib\Connection.js:88:28)
at Socket.<anonymous> (F:\dr.server\node_modules\mysql\lib\Connection.js:526:10)
at Socket.emit (events.js:400:28)
at addChunk (internal/streams/readable.js:290:12)
--------------------
at Protocol._enqueue (F:\dr.server\node_modules\mysql\lib\protocol\Protocol.js:144:48)
at Connection.query (F:\dr.server\node_modules\mysql\lib\Connection.js:198:25)
at Object.userRegistration (F:\dr.server\db.js:29:18)
at F:\dr.server\routes\users.js:12:8
at zalgoSafe (F:\dr.server\node_modules\dezalgo\dezalgo.js:20:10)
at f (F:\dr.server\node_modules\once\once.js:25:25)
at IncomingForm.<anonymous> (F:\dr.server\node_modules\formidable\src\Formidable.js:183:9)
at IncomingForm.emit (events.js:400:28)
at IncomingForm._maybeEnd (F:\dr.server\node_modules\formidable\src\Formidable.js:612:10)
at QuerystringParser.<anonymous> (F:\dr.server\node_modules\formidable\src\plugins\querystring.js:36:10) {
code: 'ER_PARSE_ERROR',
errno: 1064,
sqlMessage: "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(username, password) userinfo VALUES ( 'wer', 'wer' )' at line 1",
sqlState: '42000',
index: 0,
sql: "INSERT INTO (username, password) userinfo VALUES ( 'wer', 'wer' )"
}
I know that something is wrong with my SQL queries but I am not able to figure it out.
Any help will be welcomed.
If this information isn't enough I can give specific code through github.
Not able to add a comment, yet. Have you tried to change your SQL statement to:
INSERT INTO tbl_name (col_name, col_name) VALUES ('value', 'value')
"INSERT INTO userinfo (username, password) VALUES ( 'wer', 'wer' )"
https://dev.mysql.com/doc/refman/8.0/en/insert.html
Edit:
In your post:
It is giving me an error
I know that something is wrong with my SQL queries but I am not able to figure it out.
The code above is not meant to be the answer. As I previously mentioned, not able to comment, yet. The above code is just a pointer to the correct answer. You have to change your MySQL query to the syntax above. The link provided gives you the correct syntax.
"insert into userinfo(username, password) values('wer', 'wer');"
You can use template literals to do so.
var username, password;
const registrationQueryString = `INSERT INTO (username, password) userinfo VALUES ('${username}', '${password}')`
And then use registrationQueryString as a raw query.
Bear in mind this is an ES2015 feature and should be available in any recent version of Node.js. More about template literals at MDN Web Docs
First update this query from
INSERT INTO (username, password) userinfo VALUES ( ?, ? )
to
INSERT INTO userinfo (username, password) VALUES ( ?, ? )
Please don't use this type of query
SELECT (username, password) FROM userinfo WHERE EXISTS (SELECT (username, password) FROM userinfo WHERE username = (?) AND password = (?))
Replace it with the following
const ObjQr = [
req.body.username,
req.body.password
];
const SsQl = "CALL SpSelectUser(?,?)";
query(SsQl, ObjQr, (err,results,fields) => {
if(err) {
res.send('ERROR');
}
else {
const Info= {
UserInfo : results[0]
};
res.json(Info);
}
});
Try to use StoredProcedure instead of direct query to avoid race condition and Sql-Injection.
Related
I've tried some methods but nothing works
and I'm trying to change
Anyone can give me a little trick to create this function in node js?
Your suggestions will be very helpful for me to solve it
//router_register.js
// Definisikan router dari express
const router = require('express').Router();
// Ambil index.js dari controller dan panggil variabel didalamnya
const registerController = require('../controllers').register;
// Definisikan middleware verify.js
const verifyUser = require('../configs/verify');
// Rute 'http://localhost:5050/register/' digunakan untuk menampilkan form register
router.get('/', verifyUser.isLogout, registerController.formRegister);
// Rute 'http://localhost:5050/register/save' digunakan untuk menyimpan data yang diinput user saat register
router.post('/save', verifyUser.isLogout, registerController.saveRegister);
// Export agar dapat dibaca oleh express
module.exports = router;
//controller_register
const config = require('../configs/database');
let mysql = require('mysql');
let pool = mysql.createPool(config);
pool.on('error', (err)=> {
console.error(err);
});
module.exports = {
formRegister(req, res) {
res.render("login", {
// Definisikan semua varibel yang ingin ikut dirender kedalam register.ejs
url: 'http://localhost:5050/',
});
},
saveRegister(req, res) {
let username = req.body.username;
let email = req.body.email;
let password = req.body.pass;
if (username && email && password) {
pool.getConnection(function(err, connection) {
if (err) throw err;
connection.query(
`INSERT INTO table_user (user_name, user_email, user_password) VALUES (?,?,SHA2(?,512)); `, [username, email, password], function (error, results) {
if (error) throw error;
req.flash('color', 'success');
req.flash('status', 'Yes..');
req.flash('message', 'Registrasi berhasil');
res.redirect('/login');
});
connection.release();
})
} else {
res.redirect('/login');
res.end();
}
}
}
And please tell me which parts I should fix to make it even better for this coding
You have a couple of options. May be even both to get a robust solution. As you asked for general direction, instead of giving you exact code, I will try to point you in right direction.
In your saveRegister function, before you run INSERT, using email, you can run another query to fetch any existing user's with the incoming email address. If you find one, throw an exception for user trying to register with existing email.
To make this even better, you can add a UNIQUE constraint on your table in the database for the user_email column. This way if you do try to save another user with a duplicate email, you should get an exception that your try block will catch.
All the best. Please update the question with specifics if you try this approach and still need more help.
For context, I'm trying to send a one time link to the user's email as a reset password link that will take them to the reset password page if the jwt token is successfully verified. I followed a tutorial and created a dummy version where user info was stored locally and it worked perfectly. But when I try to implement into my main project which pulls user data from mySQL I keep getting a malformed error, I am checking all the values and everything matches including checking the token on the jwt website to see if it return the correct info which it does so I'm very confused as to what I've done wrong. The only thing that changes between the test and main project is where the data is pulled from. Here is my code for this part of the project:
// Create and send link
router.post('/forgot-password', (req, res, next) => {
var email = req.body.email
db.query('SELECT * FROM users_test WHERE email = ?', [ email ], (error, results) => {
if (results.length < 1) {
res.send('no user')
return
}
const user = results[0]
const secret = process.env.JWT_SECRET + user.password
const payload = {
email: email,
id: user.id
}
const token = jwt.sign(payload, secret)
const link = `http://localhost:5000/auth/reset-password/${user.id}/${token}`
console.log(link)
res.send('sent')
})
})
// verify token and display password reset page
router.get('/reset-password/:id/:token')= (req, res, next) => {
const { id, token } = req.params
db.query('SELECT * FROM users_test WHERE id = ?', [ id ], (error, results) => {
if (error) {
console.log(error)
}
const user = results[0]
const secret = process.env.JWT_SECRET + user.password
res.json({secret})
try {
var payload = jwt.verify(token, secret)
res.render('reset-password.hbs')
}
catch (e) {
console.log(e)
}
})
}
The line the error is point at: var payload = jwt.verify(token, secret)
The error I'm getting:
throw err; // Rethrow non-MySQL errors
^
JsonWebTokenError: jwt malformed
at Object.module.exports [as verify] (C:\Users\winba\Desktop\SecureSoftware\Secure-Software-02\node_modules\jsonwebtoken\verify.js:63:17)
at Query.<anonymous> (C:\Users\winba\Desktop\SecureSoftware\Secure-Software-02\controllers\auth.js:497:29)
at Query.<anonymous> (C:\Users\winba\Desktop\SecureSoftware\Secure-Software-02\node_modules\mysql\lib\Connection.js:526:10)
at Query._callback (C:\Users\winba\Desktop\SecureSoftware\Secure-Software-02\node_modules\mysql\lib\Connection.js:488:16)
at Query.Sequence.end (C:\Users\winba\Desktop\SecureSoftware\Secure-Software-02\node_modules\mysql\lib\protocol\sequences\Sequence.js:83:24)
at Query._handleFinalResultPacket (C:\Users\winba\Desktop\SecureSoftware\Secure-Software-02\node_modules\mysql\lib\protocol\sequences\Query.js:149:8)
at Query.EofPacket (C:\Users\winba\Desktop\SecureSoftware\Secure-Software-02\node_modules\mysql\lib\protocol\sequences\Query.js:133:8)
at Protocol._parsePacket (C:\Users\winba\Desktop\SecureSoftware\Secure-Software-02\node_modules\mysql\lib\protocol\Protocol.js:291:23)
at Parser._parsePacket (C:\Users\winba\Desktop\SecureSoftware\Secure-Software-02\node_modules\mysql\lib\protocol\Parser.js:433:10)
at Parser.write (C:\Users\winba\Desktop\SecureSoftware\Secure-Software-02\node_modules\mysql\lib\protocol\Parser.js:43:10)
Any help or ideas as to where the error is coming from would be appreciated, thank you.
Try with following changes
const link = `http://localhost:5000/auth/reset-password/${user.id}/${JSON.stringify(token)}`
var payload = jwt.verify(JSON.parse(token), secret)
I am new to node.js and learning it for quite few days and now I'm stuck with this app.post which is not working for me. If possible please let me know how to do app.update so it might be a big help in my learning process.
Kindly waiting for reply.
const mysql = require('mysql');
const express = require('express');
var app = express();
const bodyparser = require('body-parser');
app.use(bodyparser.urlencoded({extended: false}));
app.use(bodyparser.json());
app.listen(8000);
var mysqlconnection = mysql.createConnection(
{
host: 'localhost',
user: 'Naveen',
password: '',
database: 'employeedb',
multipleStatements: true
}
);
mysqlconnection.connect((err)=>{
if(!err)
console.log("DB connection successfull");
else
console.log('DB connection failed \n Error : '+ JSON.stringify(err, undefined, 2) );
});
app.post('/employee' ,function (req, res, next) {
Name = req.query.Name,
Empcode = req.query.Empcode,
Salary = req.query.Salary
let sql = "INSERT INTO employee (Name, Empcode, Salary) VALUES (? , ?, ?)";
mysqlconnection.query('sql, (Name, Empcode, Salary) ', (err, rows, fields) => {
if (!err)
res.send("Insert succeed");
else
console.log(err);
});
});
```
and then I get these error messages:
**PS C:\xampp\htdocs\first app> node index.js DB connection successfull Error: ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'sql, (Name, Empcode, Salary)' at line 1
(C:\xampp\htdocs\first app\node_modules\express\lib\router\index.js:275:10) { code: 'ER_PARSE_ERROR', errno: 1064, sqlMessage: "You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'sql, (Name, Empcode, Salary)' at line 1", sqlState: '42000', index: 0, sql: 'sql, (Name, Empcode, Salary) ' }**
You have typo in your query.
// WRONG
mysqlconnection.query('sql, (Name, Empcode, Salary) ', (err, rows, fields)...
It should not be inside quotes, and variables should be an array.
// CORRECT
mysqlconnection.query(sql, [Name, Empcode, Salary], (err, rows, fields)...
The error is clear. It is saying "You have an error in your SQL syntax". And you should check your syntax at "near 'sql, (Name, Empcode, Salary)'".
This line here
mysqlconnection.query('sql, (Name, Empcode, Salary) ',
you are passing the string literal "sql, (Name, Empcode, Salary) ", while you meant to pass in the variable sql that you created in the line above.
Trying to add a row to a mysql table using node.js, but keep getting a syntax error. New to both node/express and MySQL (downloaded the most recent versions of both a few days ago). Have compared my code with other examples and cannot figure out what is driving the error for the life of me. Code and console output below.
const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const passport = require('passport');
const mysql = require('mysql');
const con = mysql.createConnection({
host: 'localhost',
user: 'theuser',
password: 'thepassword',
database: 'thedatabase'
});
con.connect(function(err) {
if (err) throw err;
console.log('User Connected!');
});
const date1 = new Date();
const newUser = {
first_name: first_name1,
last_name: last_name1,
email: email1,
password: password1,
date: date1
};
const newUser_val = Object.values(newUser)
console.log(newUser_val)
const sql = "INSERT INTO webusers (first_name, last_name, email, password, register_date) VALUES ?";
con.query(sql, [newUser_val], function (err, result, fields) {
if(result) {
req.flash('success_msg', 'You are now registered');
res.redirect('../')
} else {
console.log(err);
};
});
And here is the relevant console output
User Connected!
[
'Pete',
'Sample',
'pete#gmail.com',
'$2a$10$6ufJWiCaubg8WjE.0AHqrOFi0z3W97mSN48v.vdO7pcl20ZPRBhXW',
2020-03-31T18:54:16.474Z
]
code: 'ER_PARSE_ERROR',
errno: 1064,
sqlMessage: "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''Pete', 'Sample', 'pete#gmail.com', '$2a$10$6ufJWiCaubg8WjE.0AHqrOFi0z3W97mSN48v' at line 1", sqlState: '42000',
index: 0,
sql: "INSERT INTO webusers (first_name, last_name, email, password, register_date) VALUES 'Pete', 'Sample', 'pete#gmail.com', '$2a$10$6ufJWiCaubg8WjE.0AHqrOFi0z3W97mSN48v.vdO7pcl20ZPRBhXW', '2020-03-31 14:54:16.474'"
}
Not sure why my question was down voted without any comment, but alas I figured it out. "?" needs parentheses as corrected in code below:
var sql = "INSERT INTO webusers (first_name, last_name, email, password, register_date) VALUES ( ? );";
These parentheses are missing from a lot of the examples out there and were necessary to make my code work... hope it helps.
Somewhat new to this, but I'm having an issue inserting a variable into my sqlite3 query. I get the error { [Error: SQLITE_ERROR: no such column: shmee] errno: 1, code: 'SQLITE_ERROR' } where shmee in this case is req.body.username
Not sure what I'm doing wrong here? Any guidance?
app.post('/users/login', function (req, res) {
console.log(req.body)
var query = "SELECT username, password FROM users WHERE username = "+req.body.username+";"
db.all(query, function (err, data) {
if (err) {
console.log(err);
} else if (req.body.password === data.password) {
//set cookie with user info
req.session.user = data;
res.redirect('/users/'+data.username);
} else {
console.log(data)
console.log('password not correct');
res.redirect('/cbt');
}
})
});
Do not concatenate data into query strings; this is a serious source of security vulnerabilities!
Use query parameters; wherever you want to pass data into a query, put a ?, and pass it as an additional argument to run:
db.run("SELECT username, password FROM users WHERE username = ?",
username,
function(err, data) {...});
Also hash your passwords.