I'm working on a REST API node/express app. For my 'signup' route, where a user uses the api to sign up for the service, it takes a POST'ed JSON object. Inside this function I want to check against the mongo db to make sure that this user doesn't already exist.
The problem is I need to get the username from the posted json information, but every attempt I have made has failed. The lines that attempt to log the req.body.username and req.body.password always return 'undefined'. What am I doing wrong?
Here's the code I have so far is below:
exports.signup = function(req, res) {
// todo: somehow verify that username, password, email and phone number are all provided.
// do not write into the collection unless we know all the information has been provided.
// maybe access the JSON elements to make sure they are not null
// todo: also make sure a record doesn't already exist for this uer
var user = req.body;
// need to get the username here somehow
var JSONuser = JSON.stringify(user);
// console.log('user: ' + user);
console.log('userJSON: ' + JSON.stringify(user));
console.log('username: ' + req.body.username);
console.log('password: ' + req.body.password);
db.collection('users', function(err, collection){
//if ( collection.findOne({}) ) { // make sure the user doesn't already exist here
collection.insert(user, {safe:true}, function(err, result){
if(err){
res.send({'error':'An error has occured'});
} else {
console.log('Success: ' + JSON.stringify(result[0]));
res.send(result[0]);
}
})
//}
});
}
By default in express, you don't have access to those variables through dot syntax. You would have to parse the response. Luckily, we have a package for that.
Use body-parser middle ware for easy access to post variables.
// install it
bash$: npm install body-parser
// require it in your project
bodyParser = require('body-parser');
// `use` it in your express app
app.use(bodyParser.urlencoded({ extended: true}));
// now you your post values are available on the req.body.postVariableName
I use this in almost all of my projects, it just makes it easy.
* EDIT *
I looked at your repo and everything actually looks fine as it pertains the reading of parsed values; however, they way you are console logging them may be where you are getting confused. I rewrote your signin route so I could explain better.
exports.signin = function(req, res) {
var user = req.body;
console.log('req.body: ' + JSON.stringify(user));
console.log('Signing In As User: ' + user.username);
console.log('Password: ' + user.password);
res.send('You just signed in!');
}
I tested this my opening up another terminal and curling a JSON post.
curl -H "Content-Type: application/json" -X POST -d '{"username":"testuser","password":"testpassword"}' http://localhost:3000/signin
As you can see it should work.
Some things worth mentioning. When you wrote console.log('req.body: ' + req.body);. You are not going to see the data you want. You are going to see req.body: [object] in the output because javascript is going to render this as req.body.toString() which is just the identifier. If you want to post the code, use JSON.stringify(req.body) or use console.dir(req.body).
Second, req.body will just give u access the body object.
// this is just user.toString() which is again [object]
console.log('Signing In As User: ' + user);
// You need to use the dot syntax to get user.username
console.log('Signing In As: " + user.username);
If you are stilling seeing issues, its because of the way you are making posts localhost, not because of your code.
Related
I'm working on a project and I have the following issue.
I want to implement logic for user login with Passport API but I'm having difficulties of understanding how it works, especially the way I want to implement it (with plain SQL queries). I have gone thru several tutorials which explain how this can be done ,but the problem is that in them it is shown only with ORMs, and I do not want it that way. I've wrote a few thousand lines of code so far ,but without success which were deleted after this of course and this is the reason I haven't provided any code below.
I'm using MySQL and Express as frameworks to build the website. If you have any brief or advanced idea of how things can happen I will be happy to hear from you.
Thanks in advance !
Passport can be quite confusing at times, I'll give that to you! I'm assuming based on your question that you want to use the "local" login strategy and not offer something like Google or GitHub Single Sign On. I'll also assume you want to use "Sessions" (cookies) rather than something like JWT.
To do this you'll need to first configure passport with your express app up front. This requires you to initialise passport and a session store (you can use MySQL if you like, or something like Redis).
Then you need to configure your "strategy" which in our cases is the local strategy.
I'll run you through an example with some code that shows how this can be done. I'll shove this all into one code snippet but you may wish to break this out into several files.
Snippet you can clone:
https://gist.github.com/BlueHatbRit/5d07d3f98d41d536a776b74fcb843174
Mirrored here for answer longevity:
const express = require('express');
const session = require('express-session');
const bodyParser = require('body-parser');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
// Create the express app
const app = express();
// Initialise express-session module effectively deals with serilaising some
// form of ID in a cookie which is secured with the given secret. In this case
// express then remembers this ID in memory. When this cookie is handed
// back to your server, express-session takes that ID and matches it up to
// the data it has stored against that ID in memory. Remember, in production
// you will most probably want to hook this up to some sort of data store,
// either Redis, MySQL, etc...
app.use(session({ secret: "cats" }));
// We need some body parser setup to use Passport with express
// you can checkout the body parser and passport docs to find out why
app.use(bodyParser.urlencoded({ extended: false }));
// Now we initialise passport
app.use(passport.initialize());
// Now setup the session strategy, this happens after the express-session
// initialisation as that must run on a request first. Once we have the data
// from express-session (remember, it converted from a session ID given to
// the user via a cookie, back into the data we stored against the ID) we can
// then pull our any additional information.
app.use(passport.session());
passport.serializeUser(function(user, done) {
// This happens at the end of a request, it recieves the
// req.user object, and you can then choose what to serialise
// into the session (returning the user a new cookie with a
// session ID).
// In most cases you'll want to store as little data as possible
// so just a user.id might be fine.
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
// Assume we stored the user ID in the session in the above
// function call, we can now access it.
// You can now take "id" and pass it into your database and
// get back whatever you want in regards to the user. This may
// just be a small representation of the user, or the entire
// record.
// You can use either SQL or an ORM here. The important bit is
// that you call the "done" callback with whatever object you
// want to represent the user.
User.findById(id, function(err, user) {
// In your main request handlers, you will then call `req.user`
// and get back whatever you passed into the callback.
done(err, user);
});
});
// Now we setup the main "login" route, this will do the first round
// of authentication. It will take a username and password, will check
// those credentails and will then decide whether or not to log the user in.
passport.use(new LocalStrategy(function(username, password, done) {
// Run your SQL here to find the user by their username
// Then check their password is correct
// If something fails then call the "done" callback with a descriptive error
// otherwise call "done" with no error, and pass it the "user" object. This will
// be assigned to req.user which will then later be put through our serialize
// function above.
// In this case I'm using an ORM, but you can use something to execute raw SQL
// if you like.
User.findOne({ username: username }, function(err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: 'Incorrect username.' });
}
// This is a made up function here, you'll need to create this and fill it out
// if you're using SQL you will probably have a function called "validPassword"
// (not assigned to a user object) where you will then pass in the hashed password
// from your database, and the password they provided you (the password string in this
// case).
if (!user.validPassword(password)) {
return done(null, false, { message: 'Incorrect password.' });
}
// We have a user and the passwords match so we can return the user object!
return done(null, user);
}
});
// Now we need to mount our configured strategy to an endpoint
app.post('/login', function(req, res, next) {
passport.authenticate('local', {
successRedirect: '/dashboard', // The user logged in fine, redirect them do the dashboard
failureRedirect: '/login', // The login failed, send them back to the login page
// It is possible to use "connect-flash" here to send back the reason but that's outside of the scope of this
});
});
// Now we'll create some middleware to ensure a user is logged in when trying to access
// a protected endpoint
function protected(req, res, next) {
// req.user will only exist if they've been authenticated
if (!req.user) {
return next(new Error('nice try, but you are not logged in!');
}
return next();
}
app.get('/private-things', protected, function(req, res, next) {
// This code will only be accessible if someone goes to /private-things and
// has a valid session!
console.log(the user is logged in!);
console.log(req.user);
res.sendStatus(200);
});
A warning, I have not run this code. All the code is there though you might spot a few syntax errors and will need to write the SQL to match up to your database.
Hello i just started learning Nodejs and made a local server as a start
then i saw that most nodejs apps have config and package files i couldnt find any info on how to do a simple one or use JSON files so i tried myself this is what i got so far
this is the server file
var http = require('http');
var json = require('./package');
var fs = require('fs');
var server = http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(addr.port);
console.log('server listening at', addr.address + ':' + addr.port);
and this is the json file
{
"addr": {
"address":"http://127.0.0.1",
"port":"8081"
}
}
i know that it will work with json.address and json.port
but when i added "addr" i thought it would simplify things with addr.port
so in short an explanation would be generously accepted on why it wont/shouldnt work or what im doing wrong
First of you should have a look at some tutorials or introduction sites like:
https://www.w3schools.com/nodejs/default.asp
Second:
The package.json file is the main configuration file of your nodeJS application. Thats the config file that defines your start point of your application as well as all included modules. simply use npm init to create a default package.json file with basic information.
Third:
If you require a json into your application as you did in your example the JSON is included hierarchically. Wich means The object you required has an attribute addr which itself is a new object with an attribute address.
So the correct way to access your information is json.addr.address based on your object description
you could also do something like this:
var network = require('./settings').addr;
console.log("ip => " + network.address);
console.log("port => " + network.port);
You need to list the parent object. You have put addr.address and addr.port, this means you are directly trying to access the addr object, but the this object doesn't exist. Try doing json.addr.address and json.addr.port and it should work.
var http = require('http');
var json = require('./package');
var fs = require('fs');
var server = http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(json.addr.port);
console.log('server listening at', json.addr.address + ':' + json.addr.port);
This question already has answers here:
How to access POST form fields in Express
(24 answers)
Closed 6 years ago.
My purpose is to send a JSON object from the client-side to the server. So taking into account the following details of the client:
<script>
var onClickFunct = function() {
trial1.send({
"test": $("#input_test").val(),
});
}
</script>
Where input_test is the name of my tag in the html page.
And where trial1 is implemented with the following code:
var trial1 = {
//notifica al server una nuova registrazione
send: function(data){
$.getJSON('/tst',data);
}
}
My Server can't see the object; infact if I print req.params it shows me "undefined".
app.get('/tst',function(req){
console.log(req.params);
});
My index.html reuire the following script <script src="https://code.jquery.com/jquery-1.10.2.js"></script>
While the server require only express
Try changing:
app.get('/tst',function(req){
console.log(req.params);
});
to:
app.get('/tst',function(req){
console.log(req.query);
});
The req.params is for parameters in your routes, like:
app.get('/test/:name', function (req, res) {
console.log(req.params);
});
When you access /test/abc then the req.params.name will be "abc".
The $.getJSON() sends the data as query parameters, see:
http://api.jquery.com/jquery.getjson/
And for the query parameters you use res.query.
If it was a POST request and you wanted to access parameters passed in the request body then you would user req.body (but you would need to use a bodyParser middleware).
Remember to use GET only for reading operations, where in the query parameters you specify what you want to get or in what form, what order etc.
If you pass data to store in a database or something like that then use POST or PUT for that and pass the data in the request body (which can be JSON).
$ npm install --save body-parser
and then:
var bodyParser = require('body-parser')
app.use( bodyParser.json() ); // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
your endpoint should look like this:
app.post('/tst',function(req){
console.log(req.body);
});
then use Jquery Post:
$.post('/tst',data);
body parser install example taken from here:
How to retrieve POST query parameters?
hope it helps :)
I am looking to perform multiple actions upon receiving HTML(or EJS) form content using the POST method. I am using Node express, mongoose & mongoDB. Each of the below POST responses work individually but i am unsure how to proceed in updating multiple databases based on ONE SINGLE form submission.
// insert into passport db
app.post('/signup', passport.authenticate('local-signup',
{
successRedirect : '/index', // redirect to the secure profile section
failureRedirect : '/signup', // redirect back to the signup page if there is an error
failureFlash : true // allow flash messages
}));
//insert into my database here
[the content of in the second function is unimportant as that is working fine and has been stripped down for simplification.]
app.post('/signup', function( req, res )
{
new UserDB(
{
user_id : req.body.content,
first_name : req.body.fname,
}).save( function( err, mySite, count )
{
res.redirect( '/index' );
});
});
I have tried redirecting but the form content is not accessible after the redirect so only the first function stores the data (ie. only 1 database is filled).
How would i run both functions within
app.post('/signup',.....
{
...
});
?
Thanks in advance!
You can do this by making one function the callback of the other. This is easy because each function maintains the same Connect middleware signature, function(req, res, next), where req and res are the request and response objects created and manipulated by the application, and next is the next function to call at the end of the current function's execution.
According to the official documentation, passport.authenticate() is a normal piece of middleware. All you need to do is specify the middleware you want to be called next. Express queues middleware functions in the order in which you pass them into app.post. You can do something like this:
app.post('/signup', passport.authenticate('local-signup', {
failureRedirect : '/signup',
failureFlash : true
}),
function(req, res) {
new UserDB({
user_id : req.body.content,
first_name : req.body.fname,
}).save(function(err, mySite, count) {
res.redirect('/index');
});
});
Middleware is an extremely powerful feature of the Express framework and possibly the single most important one to master. This guide would be a great next step if you want to learn more.
I have config.js in my nodejs project
var mysql = require('mysql');
var db_name = 'node';
var client = mysql.createClient({
user: 'root',
password: 'pass',
});
client.query('USE '+db_name);
I have used it as config file for the project. How I can use this code to call a mysql query.
I have this code in user.js
var global = require('./config.js');
this.CheckUserValid = function (login, pass) {
var sql = "SELECT * FROM `user` WHERE login = ? AND pass= ?";
global.client.query(sql, [login, pass], function selectResutl(err, results, fields) {
if (!err) return results;
else
throw err;
});
}
TypeError: Cannot call method 'query' of undefined
at Object.CheckUserValid (C:\wamp\www\Node\user.js:6:19)
Can someone help me to let me know how I can do this in better way.Actually I am using asp.net mvc in my past so I have tried it. Do someone tell me the better way to write code in nodejs.
When you require() a file/module, the result you get is whatever the module is exporting through the exports property. Anything else is encapsulated in the module and cannot be accessed from the outside. In your case, at the end of config.js you can add:
exports.client = client;
This way it will be accessible whenever you require() your config.js.
This way of creating modules is defined in the CommonJS spec:
http://commonjs.org/specs/modules/1.0/
http://wiki.commonjs.org/wiki/Modules/1.1
edit: and since commonjs.org seems to be down, here is another link with information about this type of module: http://dailyjs.com/2010/10/18/modules/