I am trying to obtain a column name value or multiple column name values but I am not obtaining it. I am pretty new to Nodejs but debugging it is even difficult. Here is my code:
var express = require('express');
var app = express();
var mongodb = require('mongodb');
var MongoClient = mongodb.MongoClient;
MongoClient.connect(url, function (err, db) {
if (err) {
console.log('Unable to connect', err);
} else {
console.log('Connected');
var collection = db.collection('users');
app.get('/db', function (request, response) {
collection.find({username: request.query.username, password: request.query.password}).toArray(function(err, docs) {
docs.forEach(function(doc) {
console.log(doc.toArray());
});
});
});
}
db.close();
});
I am basically authenticating if the username and password entered in db matches to my REST query and if yes then print success or redirect to a new page or something.
For starters, unless you are actually expecting more than one "user" to share the same "username" and "password" then you are better off using .findOne() for the singular response.
Then what is returned is just a plain JavaScript object, so just reference the properties:
collection.findOne(
{
username: request.query.username,
password: request.query.password
},
function(err,doc) {
if (err) throw err;
console.log( doc.username ); // Just the username value
}
);
If course if "nothing" is returned and there is no "error" then you didn't match anything with your criteria, so either "username" or "password" is wrong.
That's as the basic excercise, but really, authentication is a wheel that was built long ago and you would likely be better of implementing an existing module to handle it.
And get rid of db.close(). The functions here are asynchronous and this will execute before anything else completes. You basically never want to call this in real world applications.
Related
How can I save that password in a variable so that I can check it with user input and authenticate.
Below is my code.
app.post('/check-user',(req,res)=>{
var user=req.body.n1;
var pass=req.body.n2;
MongoClient.connect(url,{ useNewUrlParser: true, useUnifiedTopology: true},function(err,db){
if(err) throw err;
var dbase = db.db("db");
//var query = { username: user };
dbase.collection("users").find({"username":user},{projection:{_id:0,Name:0,username:0}}).toArray(function(err, result) {
if(err) throw err;
console.log(result);
db.close();
});
});
})
app.listen(8080,()=>{})
output is [{password:'keshav'}]
If I understood you question correctly,
You should not store actual password in database. Instead you should use a module like crypto to encrypt your password and then store it. You should google for it. There are tons of articles/tutorials about authentication in NodeJS.
About checking password, you are using this line to store user's given password in the pass variable (var pass=req.body.n2;), right? So, I believe a simple comparison operator should work in your case. Example:
if (result[0].password === pass) {
console.log('Loggedin');
} else {
console.log('Login failed');
}
I was wondering if there is a way I can get a part of an object in mongo using node. For example, it would be great if I could log say the email that is being added, by using something like console.log(result.email) to get the email part of my response. Does anyone know how to do this?
Ok so I have found a way to do this. It will not work on the .find function for some reason, but will work on .findOne and .sort
MongoClient.connect(url, function(err, db) {
if (err) throw err;
var dbo = db.db("db");
let query = {
username: "username",
key: "key"
};
dbo.collection("keys").findOne(query, (function(err, result) {
var lengthboi = result.length;
console.log(result)
if (lengthboi === 1) {
//do stuff
} else {
}
}));
});
I'm relatively new to node and socketio. What I'm trying to achieve is authenticate users using passport and send total number logged user count to the view. Such that if a logged in user can see the total number of current-logged-in users and if a user logs that the count decreases or increases when someone else log-ins respectively.
Using passport.socketio to access authenticated passport user information from a socket.io connection.
In the callback, I'm storing the username in a mongoose collection, and accordingly on the logout removing the user from the collection. I get a count of the number of users in the model which I need to pass and bind to the view. Jade being the template engine. Below is how my onAuthorizeSuccess callback looks like where I try to pass the count to home.jade.
function onAuthorizeSuccess(data, accept) {
var username = data.user.username;
var User = mongoose.model('loggedusers', userSchema);
var user = new User({
username: username
});
user.save(function (err, data) {
if (err) console.log(err);
else {
console.log('Saved : ', data);
}
User.count({}, function (err, c) {
console.log('Count is ' + c);
app.get('/', function (req, res) {
res.render('home', {
count: {
countData: c
}
});
});
});
});
console.log('successful connection to socket.io ');
accept(); //Let the user through
}
And in the jade view I try to set it using
li Logged Users ---> #{countData.c}
But, countData is undefined in the view.
How should I go about rendering a dynamic value from the server to the view in jade?
Any assistance much appreciated.
Thanks,
Arnab
Your variable is wrong you should use instead #{count} with:
res.render('home', {count: c});
Figured this out.
Made a function to server content over a socket, that the control helps updating on the front-end
module.exports = function (socket) {
setInterval(function () {
var UserSchema = require('mongoose').model('loggedusers');
UserSchema.count({}, function(err, c){
console.log('Count is ' + c);
socket.emit('send:count', {
count: c
});
});
}, 1000);
};
And the angular controller
angular.module('myApp.controllers', []).
controller('AppCtrl', function ($scope, socket) {
socket.on('send:count', function (data) {
$scope.count = data.count;
});
});
and in jade {{count}} and add div.container(ng-controller='AppCtrl') should give the updated count on the front-end.
Arnab
I am having trouble getting the output of a MongoDB query. When I call the save method:
db.users.save({email: "test#gmail.com", password: "test", sex: "male"},
function(err, saved) {
});
The code works, and stores the entry. However, the function (err, saved) isn't called, as far as I know. When I run this code:
var mongojs = require("mongojs");
var MONGOHQ_URL="mongodb://testUser:testPassword#paulo.mongohq.com:10085/app********";
app.get('/', function(request, response) {
var m = "hello";
var databaseUrl = MONGOHQ_URL;
var collections = ["users"];
var db = mongojs.connect(databaseUrl, collections);
var d = db.users.find({"sex":"male"}).limit(1);
response.send(d.email);
});
Then I get nothing. Is there something I'm missing?
var d = db.users.find({"sex":"male"}).limit(1) has no call back function so it goes out of scope and you dont see the response.
Two things first off i would use findOne instead of limit(1) and secondly you are missing the callback function, try this
db.users.findOne({"sex":"male"}, function (err, result) {
if(err){
console.log(err);
}else{
console.log(result);
//then do your response here
response.send(result.email);
}
});
Hope that makes sense.
I am using express as my webserver for node and everything seems to be working correctly. The only problem I am encoutering is when I load a specific page ('/learn' route) 10 times repeatedly. Once I do this, express seems to stop working, although no error is logged to the console and nothing wrong is displayed on the page. It just keeps waiting for the host in the browser. What is weird is that the problem doesn't occur if I go from the page with the problem to another page, and then back again. I can repeat this as much as I want without error. Here is my route with the problem:
var bcrypt = require('bcrypt');
var pool = require('../database.js').pool;
module.exports = function(app) {
app.get('/learn', function(req, res, next) {
var query = 'SELECT * FROM questions INNER JOIN answers ON questions.questionID = answers.questionID';
pool.getConnection(function(err, connection) {
connection.query(query, function(err, rows) {
if (err) {
throw err;
}
var data = {
name: req.session.name,
problems: rows,
};
res.render('learn.html', data);
});
});
});
app.post('/learn/checkAnswer', function(req, res) {
//get posted form data
var questionID = req.body.questionID;
var selectedAnswer = req.body.selectedAnswer;
//query database
pool.getConnection(function(err, connection) {
var query = connection.query('SELECT correctAnswer FROM questions WHERE questionID = ?', questionID, function(err, rows) {
res.send({
correctAnswer: rows[0].correctAnswer
});
});
});
});
};
I'm not sure if this makes a difference, but I am using handlebars as my rendering engine instead of jade, as well as node-mysql for my database.
10 is the default size of the node-mysql pool. And since you're not ending the connections retrieved with pool.getConnection, the 11th request will wait indefinitely for a free connection.
Easy to fix:
connection.query(query, function(err, rows) {
connection.end(); // end the connection as soon as possible,
// so it's returned to the pool and can be reused.
if (err) ...
});