I am using nodejs and express to connect my local mysql db, everythings look working well except no response when Iam trying to test the API in postman.
here is my code in server.js
//add sales
app.post('/sales',(req, res) => {
var POST_SALES_QUERY = {
username: req.body.username,
password: req.body.password,
fullname: req.body.fullname
}
if (!POST_SALES_QUERY) {
return res.status(400).send({ err: true, message: 'Please username' });
}
dbConn.query("INSERT INTO user_tbl SET ?", (POST_SALES_QUERY, err, results) => {
if(err){
console.log(err);
} else {
return res.send(JSON.stringify({"status": 200, "err" : null, "response": results}));
}
});
});
and in Postman, I get this:
any idea what the problem appears here?
app.post('/sales',(req, res) => {
var POST_SALES_QUERY = {
username: req.body.username,
password: req.body.password,
fullname: req.body.fullname
}
if (!POST_SALES_QUERY) {
return res.status(400).send({ err: true, message: 'Please username' });
}
let query = `INSERT INTO user_tbl (username, password, fullname) VALUES ('${POST_SALES_QUERY.username}','${POST_SALES_QUERY.password}','${POST_SALES_QUERY.fullname}')`;
dbConn.query(query,function(err,results) {
if(err){
console.log(err);
} else {
return res.status(200).json({"status": 200,"err": null,"response": results});
}
});
});
You need to tell express to treat the body as json, by calling the following codes:
app.use(express.json())
As per the documentation:
This is a built-in middleware function in Express. It parses incoming requests with JSON payloads and is based on body-parser.
Related
I'm trying to do a sample register without JWT using MVC in nodejs, express and mysql so when I run my code and I have an error :
TypeError: Cannot read properties of undefined (reading 'firstName') at exports.register
here is my code :
AuthController
const AuthModel = require('../models/Auth')
// Create and Save a new User
exports.register = (req, res) => {
// Validate request
if (!req.body) {
res.status(400).send({
message: "Content can not be empty!"
});
}
// Create user
const user = new AuthModel({
firstName: req.body.firstName,
lastName: req.body.lastName,
email: req.body.email,
password: req.body.password
});
// Save user in the database
AuthModel.createUser(user, (err, data) => {
if (err)
res.status(500).send({
message:
err.message || "Some error occurred while registring."
});
else res.send(data);
});
};
AuthModel
const AuthModel = function(table){
this.firstName = table.firstName;
this.lastName = table.lastName;
this.email = table.email;
this.password = table.password;
}
AuthModel.createUser = ( newUser, result ) =>{
db.query("INSERT INTO users SET ?", newUser, (err, res) => {
if (err) {
console.log("error: ", err);
result(err, null);
return;
}
console.log("User are registed: ", { id: res.insertId, ...newUser });
result(null, { id: res.insertId, ...newUser });
});
};
It seems to me as if the req.body is undefined. I think you might need something like body-parser, which has been added into the core of Express starting with version 4.
Try adding this middleware to your entrypoint: app.use(express.json());
See more here: http://expressjs.com/en/api.html#express.json
In your exports.register, you .send() if the body is undefined. That doesn't mean the rest of the code won't be executed.
Replace:
res.status(400).send({
message: "Content can not be empty!"
});
by
return res.status(400).send({
message: "Content can not be empty!"
});
this is my login post method in the reactjs frontend
const login = () => {
Axios.post("http://localhost:3001/api/users/login", {
email: values.email,
password: values.password,
}).then((response) => {
console.log(response.data);
}).catch(err =>{
console.log(err)
})
};
this is my expressjs server side, here i have login post method for reactjs frontend, where iam on response i want to send token to set in cookie whenever user post on login method, below is code for login post method
login: (req, res) => {
const body = req.body;
console.log("req.body :", req.body);
getUserByEmail(body.email, (err, results) => {
console.log("results :", results);
if (err) {
console.log(err);
return;
}
if (!results) {
res.json({
status: "failure",
msg: "Invalid email or password",
});
}
const result = compareSync(body.password, results.password);
const SECRET_KEY = "xyz123";
if (result) {
results.password = undefined;
const jsontoken = sign({ result: results }, SECRET_KEY, {
expiresIn: "1h",
});
// console.log(res)
res.cookie("token", jsontoken, {
httpOnly: true,
domain: "http://localhost:3000/login",
});
return res.json({
status: "Success",
msg: "login Successfully",
token: jsontoken,
});
} else {
return res.json({
status: "failure",
msg: "Invalid email or password",
});
}
});
},
What you could do, that is actually more secure, is tell the browser using headers on the response to create a cookie.
There is a header in HTTP called Set-Cookie, which is responsible to do just that, you can read more about it here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie.
The way you add it to your request on express is by calling the res.cookie function on your express request handler. I would suggest telling the cookie to be httpOnly in order for it to not be accessible through JS code, this is just a way to avoid XSS attacks.
Here you have an example to how to achieve that:
res.cookie('token', jsontoken, { httpOnly: true });
Then in order to access the cookie, you would need to use the cookieParser middleware which is responsible in putting all the cookies the client sent in req.cookies.
You use it this way:
app.use(express.cookieParser());
When I have tried to implement Google authentication in my site, using sails JavaScript, and MySQL getting error. I have using passport and passport-Google-auth Strategy. Problem is not getting data to my site from Google
My Express Config(express.js) file is like below,
var passport = require('passport')
, GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
var verifyHandler = function(token, tokenSecret, profile, done) {
process.nextTick(function() {
console.log(profile)
User.findOne({uid: profile.id}, function(err, user) {
if (user) {
return done(null, user);
} else {
var data = {
provider: profile.provider,
uid: profile.id,
name: profile.displayName
};
if (profile.emails && profile.emails[0] && profile.emails[0].value) {
data.email = profile.emails[0].value;
}
if (profile.name && profile.name.givenName) {
data.firstname = profile.name.givenName;
}
if (profile.name && profile.name.familyName) {
data.lastname = profile.name.familyName;
}
User.create(data, function(err, user) {
return done(err, user);
});
}
});
});
};
passport.serializeUser(function(user, done) {
console.log(user)
done(null, user.uid);
});
passport.deserializeUser(function(uid, done) {
User.findOne({uid: uid}, function(err, user) {
done(err, user);
});
});
module.exports.http = {
customMiddleware: function(app) {
passport.use(new GoogleStrategy({
clientID: 'Client Id here',
clientSecret: 'Secret key here',
callbackURL: 'http://localhost:1337/auth/google/callback'
}, verifyHandler));
app.use(passport.initialize());
app.use(passport.session());
}
};
module.exports.cache = {
// The number of seconds to cache files being served from disk
// (only works in production mode)
maxAge: 31557600000
};
module.exports.userlogin = {
userModel: 'user'
};
And My Auth Controller I have added code like below,
google: function(req, res) {
passport.authenticate('google',{
failureRedirect: '/login', scope: ['profile', 'email']
}, function(err, user) {
req.logIn(user, function(err) {
if (err) {
console.log(err);
res.view('500');
return;
}
res.redirect('/');
return;
});
})(req, res);
},
You didn't post your code, so we can't find the exact problem :/
I usually use this method for google/facebook authentication with sails.js.
I follow at first this documentation to add the authentication buttons in the frontend:
https://developers.google.com/identity/sign-in/web/sign-in
Then I post the token that I got from google/facebook to the backend where I can check if the user is banned or whatever... If everything is correct, I create an account for him in the database, I send him his password to his email and finally authenticate him using sessions
(req.session.userId = createdUser.id)
In the next time the user can log in using his email and password or just using google. And both options lead him to the same account :D
My Sails.js function in the authentication controller:
googleAuth: function(req, res) {
if (_.isUndefined(req.param('googleToken'))) {
return res.json({
success: false,
msg: 'Error! Please post your google token'
});
}
var urlToRq = "https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=" + req.param('googleToken');
// Get information about the google user with the specified access token.
request.get({url: urlToRq}, function(err, response, body) {
if(err) {
return res.json({
success: false,
msg: 'Server Error'
});
}
var receivedData = JSON.parse(body);
var userId = receivedData.sub;
var userEmail = receivedData.email;
var emailVerified = receivedData.email_verified;
var userName = receivedData.name;
var userPicture = receivedData.picture;
if (emailVerified == false) {
return res.json({
success: false,
msg: 'Your email is not verified'
});
}
else {
// AUTHENTICATION VERIFIED, YOU CAN SAVE THE CONNECTED USER IN A SESSION, OR ADD HIM TO THE DATABASE AS A NEW ACCOUNT, OR CHECK IF HE HAS A PREVIOUS ACCOUNT OR WHATEVER YOU WANT...
}
});
},
Of course don't forget to run npm install request --save
If anyone needs the facebookAuth function just tell me :D I will post it for you :)
I'm trying implement NodeJS authentification with express, sequelize, and mysql, but i'm blocked. I get login and password values by webservice. I want to match them with database value :
app.get('/login', function (req, res, err) {
var whereUser = {
login: req.query.login,
password: req.query.password
}
if (!req.query.login || !req.query.password) {
res.send('login failed');
//Here my code is wrong !
I try to compare login and password values with database login and passwword values
} else if (req.query.login && req.query.password == UsrPerson.findOne({ where: whereUser })) {
console.log("auth ok")
req.session.user = "amy";
req.session.admin = true;
res.send("login success!");
} else {
console.log("ERROR")
res.send(err)
}
});
How can I do that ? Thank you
app.get('/login', function (req, res, err) {
const { login, password } = req.query;
UsrPerson
.findOne({
where: {
login: login,
password: password
}
})
.then((foundUser) => {
if(!foundUser){
res.send('login failed');
} else {
console.log("auth ok");
req.session.user = "amy";
req.session.admin = true;
res.send("login success!");
}
})
.catch((err) => {
console.log('ERROR');
res.send(err);
});
});
You want to compare if the user with the given username and password combination exists.
And seems like you are storing the password without any encryption, in plain text. This is not secure at all. You have to use a library like bcrypt and only store the encrypted password in your database
The findOne method from sequelize return an instance object of the model.
that means than you can't compare a password to an instance.
The second problem is the findOne method is asynchronous, you need to await it and have an async method.
app.get('/login', async function (req, res, err) {
var whereUser = {
login: req.query.login,
password: req.query.password
}
if (!req.query.login || !req.query.password) {
res.send('login failed');
} else {
// The following code return an instance of the user if it was found.
const user = await UsrPerson.findOne({ where: whereUser }))
// If the user was not found that means the credentials was wrong.
if (user) {
console.log("auth ok")
req.session.user = "amy";
req.session.admin = true;
res.send("login success!");
} else {
console.log("ERROR")
res.send(err)
}
}
});
I'm working with jsonwebtoken and Im not entirely sure how it works. I have normal sign in sign up routes that should go before the .verify function. Ive used jwt many times but never had tried using routes before it.
Here is my routes files
var express = require('express');
var router = express.Router();
var usersController = require('../controllers').users;
var jwt = require('jsonwebtoken');
router.post('/signup', function(req,res,next) {
return usersController.signup(req,res);
});
router.post('/signin', function(req,res,next) {
return usersController.signin(req,res);
});
router.post('/social-signin', function(req,res,next) {
return usersController.authSignin(req,res);
});
router.use('/auth', function (req,res,next) {
jwt.verify(req.query.token, 'secret', function (err, decoded) {
if (err) {
return res.status(401).json({
title: 'You are not authorized to do that',
error: "Please sign out and sign back in"
})
}
});
next();
});
router.get('/auth', function(req,res){
return usersController.getUser(req, res);
});
router.patch('/auth/update/:userId', function(req,res) {
return usersController.update(req,res);
});
router.delete('/auth/delete', function(req,res,next) {
return usersController.destroy(req,res);
});
module.exports = router;
Im receiving this error when doing a GET request for getUser.
HttpErrorResponse {headers: HttpHeaders, status: 401, statusText: "Unauthorized", url: "http://localhost:3000/user/auth?token=eyJhbGciOiJI…3Njd9.FE3sYhOSFhfhnxkACKSmclcHEWKVhpItuAMqBl-A-5w", ok: false, …}
error
:
{title: "You are not authorized to do that", error: "Please sign out and sign back in"}
headers
:
HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, lazyInit: ƒ}
message
I know its probably simple but I just have no idea.
*** Here is the code for getUser
getUser: function getUser(req, res) {
var decoded = jwt.decode(req.query.token);
return User.findOne({
where: {
id: decoded.user.id
}
}).then(function(user){
return res.status(200).json({
title: "User found",
obj: user
});
}).catch(function(error) {
return res.status(400).json({
title: 'There was an error getting user!',
error: error
});
});
},
In your auth, try:
router.use('/auth', function (req,res,next) {
jwt.verify(req.query.token, 'secret', function (err, decoded) {
if (err) {
return next(new Error('You are not authorized to do that'));
}
});
next();
});
This is still an issue
Since your getUser returns a Promise, and you are just returning that from your route. I believe you want to wait on the result of the Promise, before returning from your route.