Thinkster.io Tutorial Section: Create an account using the Register request in PostmanNodeJs, Mocha and MongooseNode emitters with expressWhy this error coming while running nodejs server?PUT/ update operation fails in $resource AngularJS client in rest based app (mongoose insert / update issue).not getting expected result while using passport in nodejs for authenticationUndefined _id populate with express, moongose/MongoDB on NodejsExpress req.body not WorkingI got an empty array in sub document array saving using mongoose ( MEAN stack)Sails How to redirect page when bad request/400 error occurs?
What could a reptilian race tell by candling their eggs?
How to test CRUD and FLS in unit tests?
One folder having two different locations on Ubuntu 18.04
If two black hole event horizons overlap (touch) can they ever separate again?
Does the Pi 4 resolve the Ethernet+USB bottleneck issue of past versions?
How can a valley surrounded by mountains be fertile and rainy?
Is the location of an aircraft spoiler really that vital?
Should I report a leak of confidential HR information?
Why does the same classical piece sound like it's in a different key in different recordings?
What are good ways to spray paint a QR code on a footpath?
Does a return economy-class seat between London and San Francisco release 5.28 t of CO2e?
Do the 26 richest billionaires own as much wealth as the poorest 3.8 billion people?
What exactly did Ant-Man see that made him say that their plan worked?
Could the Q destroy the universe?
Equivalence of Put Pricing Formulas
Could human civilization live 150 years in a nuclear-powered aircraft carrier colony without resorting to mass killing/ cannibalism?
How hard is it to sell a home which is currently mortgaged?
Is it bad to describe a character long after their introduction?
Does any Greek word have a geminate consonant after a long vowel?
Who voices the character "Finger" in The Fifth Element?
In native German words, is Q always followed by U, as in English?
Boolean Difference with Offset?
Could a Weapon of Mass Destruction, targeting only humans, be developed?
Why would anyone even use a Portkey?
Thinkster.io Tutorial Section: Create an account using the Register request in Postman
NodeJs, Mocha and MongooseNode emitters with expressWhy this error coming while running nodejs server?PUT/ update operation fails in $resource AngularJS client in rest based app (mongoose insert / update issue).not getting expected result while using passport in nodejs for authenticationUndefined _id populate with express, moongose/MongoDB on NodejsExpress req.body not WorkingI got an empty array in sub document array saving using mongoose ( MEAN stack)Sails How to redirect page when bad request/400 error occurs?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
Thinkster.io Link
https://thinkster.io/tutorials/node-json-api/setting-up-users-and-authentication
I'm receiving a 404 on any postman request i send to my app api.
This is the error i'm getting from postman
"There was an error in evaluating the test script: JSONError: Unexpected token '<' at 1:1 ^"
but it's really a 404, i get this in my console "POST /users 404 0.396 ms - 145"
Postman screenshot
I thought it may be my routing but i went through the tutorial again and i'm now thinking i'm doing something wrong in Postman. I worked through Thinksters Postman walk through and all my test work on their servers but idk what i'm missing.
app.js
var fs = require('fs'),
http = require('http'),
path = require('path'),
methods = require('methods'),
express = require('express'),
bodyParser = require('body-parser'),
session = require('express-session'),
cors = require('cors'),
passport = require('passport'),
errorhandler = require('errorhandler'),
mongoose = require('mongoose');
var isProduction = process.env.NODE_ENV === 'production';
// Create global app object
var app = express();
app.use(cors());
// Normal express config defaults
app.use(require('morgan')('dev'));
app.use(bodyParser.urlencoded( extended: false ));
app.use(bodyParser.json());
app.use(require('method-override')());
app.use(express.static(__dirname + '/public'));
app.use(session( secret: 'conduit', cookie: maxAge: 60000 , resave: false, saveUninitialized: false ));
if (!isProduction)
app.use(errorhandler());
if(isProduction)
mongoose.connect(process.env.MONGODB_URI);
else
mongoose.connect('mongodb://localhost/conduit');
mongoose.set('debug', true);
require('./models/User');//Be sure to include models before routes so that our routes will be able to use our models. this allows us to use the user model with auth
require('./config/passport');//username and password auth middleware for login endpoint /login
app.use(require('./routes'));
/// catch 404 and forward to error handler
app.use(function(req, res, next)
var err = new Error('Not Found');
err.status = 404;
next(err);
);
/// error handlers
// development error handler
// will print stacktrace
if (!isProduction)
app.use(function(err, req, res, next) );
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) );
// finally, let's start our server...
var server = app.listen( process.env.PORT || 3000, function()
console.log('Listening on port ' + server.address().port);
);
routes/user.js
var mongoose = require('mongoose');
var router = require('express').Router();
var passport = require('passport');
var User = mongoose.model('User');
var auth = require('../auth');
//We rely on Mongoose validations to ensure that users are created with a username or password. When user.save() is called, a promise is returned for us to handle. If the promise is resolved, that means the user was saved successfully, and we return the user's auth JSON. If the promise gets rejected, we use .catch() to pass the error to our error handler.
router.post('/users', function(req, res, next)
var user = new User();
user.username = req.body.user.username;
user.email = req.body.user.email;
user.setPassword(req.body.user.password);
user.save().then(function()
return res.json(user: user.toAuthJSON());
).catch(next);
);
//First, we're checking to make sure an email and password were provided by the front-end and respond with a 422 status code if they're not. Then, we pass the incoming request to passport.authenticate and specify that we want to use the local strategy we made previously (in config/passport.js). Since we're using JWTs for authentication and not using sessions, we also specify session: false to prevent Passport from serializing the user into the session. Finally, we define a callback for the passport strategy (this gets used as the done function in our LocalStrategy in config/passport.js) that will respond to the client based off if the authentication was successful or not.
router.post('/users/login', function(req, res, next)
if(!req.body.user.email)
return res.status(422).json(errors: email: "can't be blank");
if(!req.body.user.password)
return res.status(422).json(errors: password: "can't be blank");
//While we can implement this functionality without the use of Passport in our route, an advantage to using Passport is that it gives us the ability to add other authentication strategies such as OAuth in the future.
passport.authenticate('local', session: false, function(err, user, info)
if(err) return next(err);
if(user)
user.token = user.generateJWT();
return res.json(user: user.toAuthJSON());
else
return res.status(422).json(info);
)(req, res, next);
);
router.get('/user', auth.required, function(req, res, next)
User.findById(req.payload.id).then(function(user)
if(!user) return res.sendStatus(401);
return res.json(user: user.toAuthJSON());
).catch(next);
);
router.put('/user', auth.required, function(req, res, next)
User.findById(req.payload.id).then(function(user)
if(!user) return res.sendStatus(401);
// only update fields that were actually passed...
if(typeof req.body.user.username !== 'undefined')
user.username = req.body.user.username;
if(typeof req.body.user.email !== 'undefined')
user.email = req.body.user.email;
if(typeof req.body.user.bio !== 'undefined')
user.bio = req.body.user.bio;
if(typeof req.body.user.image !== 'undefined')
user.image = req.body.user.image;
if(typeof req.body.user.password !== 'undefined')
user.setPassword(req.body.user.password);
return user.save().then(function()
return res.json(user: user.toAuthJSON());
);
).catch(next);
);
module.exports = router;
routes/index.js
var router = require('express').Router();
router.use('/api', require('./api'));
module.exports = router;
routes/api/index.js
var router = require('express').Router();
router.use('/', require('./users'));
//When a middleware is defined with four arguments, it will be treated as an error handler (the first argument is always the error object). This error handler sits after all of our API routes and is used for catching ValidationErrors thrown by mongoose. The error handler then parses the error into something our front-end can understand, and then responds with a 422 status code.
router.use(function(err, req, res, next)
if(err.name === 'ValidationError')
return res.status(422).json(
errors: Object.keys(err.errors).reduce(function(errors, key)
errors[key] = err.errors[key].message;
return errors;
, )
);
return next(err);
);
module.exports = router;
models/User.js
var mongoose = require('mongoose'); //handles models/schema for mongodb i/o
var uniqueValidator = require('mongoose-unique-validator');//builting in unique combo validation
var crypto = require('crypto'); //library that generates and validates hashes
var jwt = require('jsonwebtoken');
var secret = require('../config').secret;//We need a secret to sign and validate JWT's. This secret should be a random string that is remembered for your application; it's essentially the password to your JWT's. In config/index.js there's a secret value which is set to "secret" in development and reads from an environment variable in production.
var UserSchema = new mongoose.Schema(
username: type: String, lowercase: true, unique: true, required: [true, "can't be blank"], match: [/^[a-zA-Z0-9]+$/, 'is invalid'], index: true,
email: type: String, lowercase: true, unique: true, required: [true, "can't be blank"], match: [/S+@S+.S+/, 'is invalid'], index: true,
image: String,
hash: String,
salt: String
, timestamps: true);
//plugging in a validator defind above, unique:true must be used for validation
UserSchema.plugin(uniqueValidator, message: 'is already taken.');
//To see if a password is valid for a particular user, we need to run the pbkdf2 with the same number of iterations and key length as our setPassword function with the salt of the user; then we need to check to see if the resulting hash matches the one that's stored in the database.
UserSchema.methods.setPassword = function(password)
this.salt = crypto.randomBytes(16).toString('hex');
this.hash = crypto.pbkdf2Sync(password, this.salt, 10000, 512, 'sha512').toString('hex');
;
//Next, we'll need a method on our model for generating a JWT (JSON Web Token). JWT's are the tokens that will be passed to the front-end that will be used for authentication. The JWT contains a payload (assertions) that is signed by the back-end, so the payload can be read by both the front-end and back-end, but can only be validated by the back-end.
UserSchema.methods.validPassword = function(password)
var hash = crypto.pbkdf2Sync(password, this.salt, 10000, 512, 'sha512').toString('hex');
return this.hash === hash;
;
//Lastly, we'll need a method on the user model to get the JSON representation of the user that will be passed to the front-end during authentication. This JSON format should only be returned to that specific user since it contains sensitive information like the JWT.
UserSchema.methods.generateJWT = function()
var today = new Date();
var exp = new Date(today);
exp.setDate(today.getDate() + 60);
return jwt.sign(
id: this._id,
username: this.username,
exp: parseInt(exp.getTime() / 1000),
, secret);
;
UserSchema.methods.toAuthJSON = function()
return
username: this.username,
email: this.email,
token: this.generateJWT(),
bio: this.bio,
image: this.image
;
;
mongoose.model('User', UserSchema);
node.js api express postman
add a comment |
Thinkster.io Link
https://thinkster.io/tutorials/node-json-api/setting-up-users-and-authentication
I'm receiving a 404 on any postman request i send to my app api.
This is the error i'm getting from postman
"There was an error in evaluating the test script: JSONError: Unexpected token '<' at 1:1 ^"
but it's really a 404, i get this in my console "POST /users 404 0.396 ms - 145"
Postman screenshot
I thought it may be my routing but i went through the tutorial again and i'm now thinking i'm doing something wrong in Postman. I worked through Thinksters Postman walk through and all my test work on their servers but idk what i'm missing.
app.js
var fs = require('fs'),
http = require('http'),
path = require('path'),
methods = require('methods'),
express = require('express'),
bodyParser = require('body-parser'),
session = require('express-session'),
cors = require('cors'),
passport = require('passport'),
errorhandler = require('errorhandler'),
mongoose = require('mongoose');
var isProduction = process.env.NODE_ENV === 'production';
// Create global app object
var app = express();
app.use(cors());
// Normal express config defaults
app.use(require('morgan')('dev'));
app.use(bodyParser.urlencoded( extended: false ));
app.use(bodyParser.json());
app.use(require('method-override')());
app.use(express.static(__dirname + '/public'));
app.use(session( secret: 'conduit', cookie: maxAge: 60000 , resave: false, saveUninitialized: false ));
if (!isProduction)
app.use(errorhandler());
if(isProduction)
mongoose.connect(process.env.MONGODB_URI);
else
mongoose.connect('mongodb://localhost/conduit');
mongoose.set('debug', true);
require('./models/User');//Be sure to include models before routes so that our routes will be able to use our models. this allows us to use the user model with auth
require('./config/passport');//username and password auth middleware for login endpoint /login
app.use(require('./routes'));
/// catch 404 and forward to error handler
app.use(function(req, res, next)
var err = new Error('Not Found');
err.status = 404;
next(err);
);
/// error handlers
// development error handler
// will print stacktrace
if (!isProduction)
app.use(function(err, req, res, next) );
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) );
// finally, let's start our server...
var server = app.listen( process.env.PORT || 3000, function()
console.log('Listening on port ' + server.address().port);
);
routes/user.js
var mongoose = require('mongoose');
var router = require('express').Router();
var passport = require('passport');
var User = mongoose.model('User');
var auth = require('../auth');
//We rely on Mongoose validations to ensure that users are created with a username or password. When user.save() is called, a promise is returned for us to handle. If the promise is resolved, that means the user was saved successfully, and we return the user's auth JSON. If the promise gets rejected, we use .catch() to pass the error to our error handler.
router.post('/users', function(req, res, next)
var user = new User();
user.username = req.body.user.username;
user.email = req.body.user.email;
user.setPassword(req.body.user.password);
user.save().then(function()
return res.json(user: user.toAuthJSON());
).catch(next);
);
//First, we're checking to make sure an email and password were provided by the front-end and respond with a 422 status code if they're not. Then, we pass the incoming request to passport.authenticate and specify that we want to use the local strategy we made previously (in config/passport.js). Since we're using JWTs for authentication and not using sessions, we also specify session: false to prevent Passport from serializing the user into the session. Finally, we define a callback for the passport strategy (this gets used as the done function in our LocalStrategy in config/passport.js) that will respond to the client based off if the authentication was successful or not.
router.post('/users/login', function(req, res, next)
if(!req.body.user.email)
return res.status(422).json(errors: email: "can't be blank");
if(!req.body.user.password)
return res.status(422).json(errors: password: "can't be blank");
//While we can implement this functionality without the use of Passport in our route, an advantage to using Passport is that it gives us the ability to add other authentication strategies such as OAuth in the future.
passport.authenticate('local', session: false, function(err, user, info)
if(err) return next(err);
if(user)
user.token = user.generateJWT();
return res.json(user: user.toAuthJSON());
else
return res.status(422).json(info);
)(req, res, next);
);
router.get('/user', auth.required, function(req, res, next)
User.findById(req.payload.id).then(function(user)
if(!user) return res.sendStatus(401);
return res.json(user: user.toAuthJSON());
).catch(next);
);
router.put('/user', auth.required, function(req, res, next)
User.findById(req.payload.id).then(function(user)
if(!user) return res.sendStatus(401);
// only update fields that were actually passed...
if(typeof req.body.user.username !== 'undefined')
user.username = req.body.user.username;
if(typeof req.body.user.email !== 'undefined')
user.email = req.body.user.email;
if(typeof req.body.user.bio !== 'undefined')
user.bio = req.body.user.bio;
if(typeof req.body.user.image !== 'undefined')
user.image = req.body.user.image;
if(typeof req.body.user.password !== 'undefined')
user.setPassword(req.body.user.password);
return user.save().then(function()
return res.json(user: user.toAuthJSON());
);
).catch(next);
);
module.exports = router;
routes/index.js
var router = require('express').Router();
router.use('/api', require('./api'));
module.exports = router;
routes/api/index.js
var router = require('express').Router();
router.use('/', require('./users'));
//When a middleware is defined with four arguments, it will be treated as an error handler (the first argument is always the error object). This error handler sits after all of our API routes and is used for catching ValidationErrors thrown by mongoose. The error handler then parses the error into something our front-end can understand, and then responds with a 422 status code.
router.use(function(err, req, res, next)
if(err.name === 'ValidationError')
return res.status(422).json(
errors: Object.keys(err.errors).reduce(function(errors, key)
errors[key] = err.errors[key].message;
return errors;
, )
);
return next(err);
);
module.exports = router;
models/User.js
var mongoose = require('mongoose'); //handles models/schema for mongodb i/o
var uniqueValidator = require('mongoose-unique-validator');//builting in unique combo validation
var crypto = require('crypto'); //library that generates and validates hashes
var jwt = require('jsonwebtoken');
var secret = require('../config').secret;//We need a secret to sign and validate JWT's. This secret should be a random string that is remembered for your application; it's essentially the password to your JWT's. In config/index.js there's a secret value which is set to "secret" in development and reads from an environment variable in production.
var UserSchema = new mongoose.Schema(
username: type: String, lowercase: true, unique: true, required: [true, "can't be blank"], match: [/^[a-zA-Z0-9]+$/, 'is invalid'], index: true,
email: type: String, lowercase: true, unique: true, required: [true, "can't be blank"], match: [/S+@S+.S+/, 'is invalid'], index: true,
image: String,
hash: String,
salt: String
, timestamps: true);
//plugging in a validator defind above, unique:true must be used for validation
UserSchema.plugin(uniqueValidator, message: 'is already taken.');
//To see if a password is valid for a particular user, we need to run the pbkdf2 with the same number of iterations and key length as our setPassword function with the salt of the user; then we need to check to see if the resulting hash matches the one that's stored in the database.
UserSchema.methods.setPassword = function(password)
this.salt = crypto.randomBytes(16).toString('hex');
this.hash = crypto.pbkdf2Sync(password, this.salt, 10000, 512, 'sha512').toString('hex');
;
//Next, we'll need a method on our model for generating a JWT (JSON Web Token). JWT's are the tokens that will be passed to the front-end that will be used for authentication. The JWT contains a payload (assertions) that is signed by the back-end, so the payload can be read by both the front-end and back-end, but can only be validated by the back-end.
UserSchema.methods.validPassword = function(password)
var hash = crypto.pbkdf2Sync(password, this.salt, 10000, 512, 'sha512').toString('hex');
return this.hash === hash;
;
//Lastly, we'll need a method on the user model to get the JSON representation of the user that will be passed to the front-end during authentication. This JSON format should only be returned to that specific user since it contains sensitive information like the JWT.
UserSchema.methods.generateJWT = function()
var today = new Date();
var exp = new Date(today);
exp.setDate(today.getDate() + 60);
return jwt.sign(
id: this._id,
username: this.username,
exp: parseInt(exp.getTime() / 1000),
, secret);
;
UserSchema.methods.toAuthJSON = function()
return
username: this.username,
email: this.email,
token: this.generateJWT(),
bio: this.bio,
image: this.image
;
;
mongoose.model('User', UserSchema);
node.js api express postman
The tutorial you are linking to is behind a paywall
– Josh
Mar 25 at 15:54
add a comment |
Thinkster.io Link
https://thinkster.io/tutorials/node-json-api/setting-up-users-and-authentication
I'm receiving a 404 on any postman request i send to my app api.
This is the error i'm getting from postman
"There was an error in evaluating the test script: JSONError: Unexpected token '<' at 1:1 ^"
but it's really a 404, i get this in my console "POST /users 404 0.396 ms - 145"
Postman screenshot
I thought it may be my routing but i went through the tutorial again and i'm now thinking i'm doing something wrong in Postman. I worked through Thinksters Postman walk through and all my test work on their servers but idk what i'm missing.
app.js
var fs = require('fs'),
http = require('http'),
path = require('path'),
methods = require('methods'),
express = require('express'),
bodyParser = require('body-parser'),
session = require('express-session'),
cors = require('cors'),
passport = require('passport'),
errorhandler = require('errorhandler'),
mongoose = require('mongoose');
var isProduction = process.env.NODE_ENV === 'production';
// Create global app object
var app = express();
app.use(cors());
// Normal express config defaults
app.use(require('morgan')('dev'));
app.use(bodyParser.urlencoded( extended: false ));
app.use(bodyParser.json());
app.use(require('method-override')());
app.use(express.static(__dirname + '/public'));
app.use(session( secret: 'conduit', cookie: maxAge: 60000 , resave: false, saveUninitialized: false ));
if (!isProduction)
app.use(errorhandler());
if(isProduction)
mongoose.connect(process.env.MONGODB_URI);
else
mongoose.connect('mongodb://localhost/conduit');
mongoose.set('debug', true);
require('./models/User');//Be sure to include models before routes so that our routes will be able to use our models. this allows us to use the user model with auth
require('./config/passport');//username and password auth middleware for login endpoint /login
app.use(require('./routes'));
/// catch 404 and forward to error handler
app.use(function(req, res, next)
var err = new Error('Not Found');
err.status = 404;
next(err);
);
/// error handlers
// development error handler
// will print stacktrace
if (!isProduction)
app.use(function(err, req, res, next) );
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) );
// finally, let's start our server...
var server = app.listen( process.env.PORT || 3000, function()
console.log('Listening on port ' + server.address().port);
);
routes/user.js
var mongoose = require('mongoose');
var router = require('express').Router();
var passport = require('passport');
var User = mongoose.model('User');
var auth = require('../auth');
//We rely on Mongoose validations to ensure that users are created with a username or password. When user.save() is called, a promise is returned for us to handle. If the promise is resolved, that means the user was saved successfully, and we return the user's auth JSON. If the promise gets rejected, we use .catch() to pass the error to our error handler.
router.post('/users', function(req, res, next)
var user = new User();
user.username = req.body.user.username;
user.email = req.body.user.email;
user.setPassword(req.body.user.password);
user.save().then(function()
return res.json(user: user.toAuthJSON());
).catch(next);
);
//First, we're checking to make sure an email and password were provided by the front-end and respond with a 422 status code if they're not. Then, we pass the incoming request to passport.authenticate and specify that we want to use the local strategy we made previously (in config/passport.js). Since we're using JWTs for authentication and not using sessions, we also specify session: false to prevent Passport from serializing the user into the session. Finally, we define a callback for the passport strategy (this gets used as the done function in our LocalStrategy in config/passport.js) that will respond to the client based off if the authentication was successful or not.
router.post('/users/login', function(req, res, next)
if(!req.body.user.email)
return res.status(422).json(errors: email: "can't be blank");
if(!req.body.user.password)
return res.status(422).json(errors: password: "can't be blank");
//While we can implement this functionality without the use of Passport in our route, an advantage to using Passport is that it gives us the ability to add other authentication strategies such as OAuth in the future.
passport.authenticate('local', session: false, function(err, user, info)
if(err) return next(err);
if(user)
user.token = user.generateJWT();
return res.json(user: user.toAuthJSON());
else
return res.status(422).json(info);
)(req, res, next);
);
router.get('/user', auth.required, function(req, res, next)
User.findById(req.payload.id).then(function(user)
if(!user) return res.sendStatus(401);
return res.json(user: user.toAuthJSON());
).catch(next);
);
router.put('/user', auth.required, function(req, res, next)
User.findById(req.payload.id).then(function(user)
if(!user) return res.sendStatus(401);
// only update fields that were actually passed...
if(typeof req.body.user.username !== 'undefined')
user.username = req.body.user.username;
if(typeof req.body.user.email !== 'undefined')
user.email = req.body.user.email;
if(typeof req.body.user.bio !== 'undefined')
user.bio = req.body.user.bio;
if(typeof req.body.user.image !== 'undefined')
user.image = req.body.user.image;
if(typeof req.body.user.password !== 'undefined')
user.setPassword(req.body.user.password);
return user.save().then(function()
return res.json(user: user.toAuthJSON());
);
).catch(next);
);
module.exports = router;
routes/index.js
var router = require('express').Router();
router.use('/api', require('./api'));
module.exports = router;
routes/api/index.js
var router = require('express').Router();
router.use('/', require('./users'));
//When a middleware is defined with four arguments, it will be treated as an error handler (the first argument is always the error object). This error handler sits after all of our API routes and is used for catching ValidationErrors thrown by mongoose. The error handler then parses the error into something our front-end can understand, and then responds with a 422 status code.
router.use(function(err, req, res, next)
if(err.name === 'ValidationError')
return res.status(422).json(
errors: Object.keys(err.errors).reduce(function(errors, key)
errors[key] = err.errors[key].message;
return errors;
, )
);
return next(err);
);
module.exports = router;
models/User.js
var mongoose = require('mongoose'); //handles models/schema for mongodb i/o
var uniqueValidator = require('mongoose-unique-validator');//builting in unique combo validation
var crypto = require('crypto'); //library that generates and validates hashes
var jwt = require('jsonwebtoken');
var secret = require('../config').secret;//We need a secret to sign and validate JWT's. This secret should be a random string that is remembered for your application; it's essentially the password to your JWT's. In config/index.js there's a secret value which is set to "secret" in development and reads from an environment variable in production.
var UserSchema = new mongoose.Schema(
username: type: String, lowercase: true, unique: true, required: [true, "can't be blank"], match: [/^[a-zA-Z0-9]+$/, 'is invalid'], index: true,
email: type: String, lowercase: true, unique: true, required: [true, "can't be blank"], match: [/S+@S+.S+/, 'is invalid'], index: true,
image: String,
hash: String,
salt: String
, timestamps: true);
//plugging in a validator defind above, unique:true must be used for validation
UserSchema.plugin(uniqueValidator, message: 'is already taken.');
//To see if a password is valid for a particular user, we need to run the pbkdf2 with the same number of iterations and key length as our setPassword function with the salt of the user; then we need to check to see if the resulting hash matches the one that's stored in the database.
UserSchema.methods.setPassword = function(password)
this.salt = crypto.randomBytes(16).toString('hex');
this.hash = crypto.pbkdf2Sync(password, this.salt, 10000, 512, 'sha512').toString('hex');
;
//Next, we'll need a method on our model for generating a JWT (JSON Web Token). JWT's are the tokens that will be passed to the front-end that will be used for authentication. The JWT contains a payload (assertions) that is signed by the back-end, so the payload can be read by both the front-end and back-end, but can only be validated by the back-end.
UserSchema.methods.validPassword = function(password)
var hash = crypto.pbkdf2Sync(password, this.salt, 10000, 512, 'sha512').toString('hex');
return this.hash === hash;
;
//Lastly, we'll need a method on the user model to get the JSON representation of the user that will be passed to the front-end during authentication. This JSON format should only be returned to that specific user since it contains sensitive information like the JWT.
UserSchema.methods.generateJWT = function()
var today = new Date();
var exp = new Date(today);
exp.setDate(today.getDate() + 60);
return jwt.sign(
id: this._id,
username: this.username,
exp: parseInt(exp.getTime() / 1000),
, secret);
;
UserSchema.methods.toAuthJSON = function()
return
username: this.username,
email: this.email,
token: this.generateJWT(),
bio: this.bio,
image: this.image
;
;
mongoose.model('User', UserSchema);
node.js api express postman
Thinkster.io Link
https://thinkster.io/tutorials/node-json-api/setting-up-users-and-authentication
I'm receiving a 404 on any postman request i send to my app api.
This is the error i'm getting from postman
"There was an error in evaluating the test script: JSONError: Unexpected token '<' at 1:1 ^"
but it's really a 404, i get this in my console "POST /users 404 0.396 ms - 145"
Postman screenshot
I thought it may be my routing but i went through the tutorial again and i'm now thinking i'm doing something wrong in Postman. I worked through Thinksters Postman walk through and all my test work on their servers but idk what i'm missing.
app.js
var fs = require('fs'),
http = require('http'),
path = require('path'),
methods = require('methods'),
express = require('express'),
bodyParser = require('body-parser'),
session = require('express-session'),
cors = require('cors'),
passport = require('passport'),
errorhandler = require('errorhandler'),
mongoose = require('mongoose');
var isProduction = process.env.NODE_ENV === 'production';
// Create global app object
var app = express();
app.use(cors());
// Normal express config defaults
app.use(require('morgan')('dev'));
app.use(bodyParser.urlencoded( extended: false ));
app.use(bodyParser.json());
app.use(require('method-override')());
app.use(express.static(__dirname + '/public'));
app.use(session( secret: 'conduit', cookie: maxAge: 60000 , resave: false, saveUninitialized: false ));
if (!isProduction)
app.use(errorhandler());
if(isProduction)
mongoose.connect(process.env.MONGODB_URI);
else
mongoose.connect('mongodb://localhost/conduit');
mongoose.set('debug', true);
require('./models/User');//Be sure to include models before routes so that our routes will be able to use our models. this allows us to use the user model with auth
require('./config/passport');//username and password auth middleware for login endpoint /login
app.use(require('./routes'));
/// catch 404 and forward to error handler
app.use(function(req, res, next)
var err = new Error('Not Found');
err.status = 404;
next(err);
);
/// error handlers
// development error handler
// will print stacktrace
if (!isProduction)
app.use(function(err, req, res, next) );
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) );
// finally, let's start our server...
var server = app.listen( process.env.PORT || 3000, function()
console.log('Listening on port ' + server.address().port);
);
routes/user.js
var mongoose = require('mongoose');
var router = require('express').Router();
var passport = require('passport');
var User = mongoose.model('User');
var auth = require('../auth');
//We rely on Mongoose validations to ensure that users are created with a username or password. When user.save() is called, a promise is returned for us to handle. If the promise is resolved, that means the user was saved successfully, and we return the user's auth JSON. If the promise gets rejected, we use .catch() to pass the error to our error handler.
router.post('/users', function(req, res, next)
var user = new User();
user.username = req.body.user.username;
user.email = req.body.user.email;
user.setPassword(req.body.user.password);
user.save().then(function()
return res.json(user: user.toAuthJSON());
).catch(next);
);
//First, we're checking to make sure an email and password were provided by the front-end and respond with a 422 status code if they're not. Then, we pass the incoming request to passport.authenticate and specify that we want to use the local strategy we made previously (in config/passport.js). Since we're using JWTs for authentication and not using sessions, we also specify session: false to prevent Passport from serializing the user into the session. Finally, we define a callback for the passport strategy (this gets used as the done function in our LocalStrategy in config/passport.js) that will respond to the client based off if the authentication was successful or not.
router.post('/users/login', function(req, res, next)
if(!req.body.user.email)
return res.status(422).json(errors: email: "can't be blank");
if(!req.body.user.password)
return res.status(422).json(errors: password: "can't be blank");
//While we can implement this functionality without the use of Passport in our route, an advantage to using Passport is that it gives us the ability to add other authentication strategies such as OAuth in the future.
passport.authenticate('local', session: false, function(err, user, info)
if(err) return next(err);
if(user)
user.token = user.generateJWT();
return res.json(user: user.toAuthJSON());
else
return res.status(422).json(info);
)(req, res, next);
);
router.get('/user', auth.required, function(req, res, next)
User.findById(req.payload.id).then(function(user)
if(!user) return res.sendStatus(401);
return res.json(user: user.toAuthJSON());
).catch(next);
);
router.put('/user', auth.required, function(req, res, next)
User.findById(req.payload.id).then(function(user)
if(!user) return res.sendStatus(401);
// only update fields that were actually passed...
if(typeof req.body.user.username !== 'undefined')
user.username = req.body.user.username;
if(typeof req.body.user.email !== 'undefined')
user.email = req.body.user.email;
if(typeof req.body.user.bio !== 'undefined')
user.bio = req.body.user.bio;
if(typeof req.body.user.image !== 'undefined')
user.image = req.body.user.image;
if(typeof req.body.user.password !== 'undefined')
user.setPassword(req.body.user.password);
return user.save().then(function()
return res.json(user: user.toAuthJSON());
);
).catch(next);
);
module.exports = router;
routes/index.js
var router = require('express').Router();
router.use('/api', require('./api'));
module.exports = router;
routes/api/index.js
var router = require('express').Router();
router.use('/', require('./users'));
//When a middleware is defined with four arguments, it will be treated as an error handler (the first argument is always the error object). This error handler sits after all of our API routes and is used for catching ValidationErrors thrown by mongoose. The error handler then parses the error into something our front-end can understand, and then responds with a 422 status code.
router.use(function(err, req, res, next)
if(err.name === 'ValidationError')
return res.status(422).json(
errors: Object.keys(err.errors).reduce(function(errors, key)
errors[key] = err.errors[key].message;
return errors;
, )
);
return next(err);
);
module.exports = router;
models/User.js
var mongoose = require('mongoose'); //handles models/schema for mongodb i/o
var uniqueValidator = require('mongoose-unique-validator');//builting in unique combo validation
var crypto = require('crypto'); //library that generates and validates hashes
var jwt = require('jsonwebtoken');
var secret = require('../config').secret;//We need a secret to sign and validate JWT's. This secret should be a random string that is remembered for your application; it's essentially the password to your JWT's. In config/index.js there's a secret value which is set to "secret" in development and reads from an environment variable in production.
var UserSchema = new mongoose.Schema(
username: type: String, lowercase: true, unique: true, required: [true, "can't be blank"], match: [/^[a-zA-Z0-9]+$/, 'is invalid'], index: true,
email: type: String, lowercase: true, unique: true, required: [true, "can't be blank"], match: [/S+@S+.S+/, 'is invalid'], index: true,
image: String,
hash: String,
salt: String
, timestamps: true);
//plugging in a validator defind above, unique:true must be used for validation
UserSchema.plugin(uniqueValidator, message: 'is already taken.');
//To see if a password is valid for a particular user, we need to run the pbkdf2 with the same number of iterations and key length as our setPassword function with the salt of the user; then we need to check to see if the resulting hash matches the one that's stored in the database.
UserSchema.methods.setPassword = function(password)
this.salt = crypto.randomBytes(16).toString('hex');
this.hash = crypto.pbkdf2Sync(password, this.salt, 10000, 512, 'sha512').toString('hex');
;
//Next, we'll need a method on our model for generating a JWT (JSON Web Token). JWT's are the tokens that will be passed to the front-end that will be used for authentication. The JWT contains a payload (assertions) that is signed by the back-end, so the payload can be read by both the front-end and back-end, but can only be validated by the back-end.
UserSchema.methods.validPassword = function(password)
var hash = crypto.pbkdf2Sync(password, this.salt, 10000, 512, 'sha512').toString('hex');
return this.hash === hash;
;
//Lastly, we'll need a method on the user model to get the JSON representation of the user that will be passed to the front-end during authentication. This JSON format should only be returned to that specific user since it contains sensitive information like the JWT.
UserSchema.methods.generateJWT = function()
var today = new Date();
var exp = new Date(today);
exp.setDate(today.getDate() + 60);
return jwt.sign(
id: this._id,
username: this.username,
exp: parseInt(exp.getTime() / 1000),
, secret);
;
UserSchema.methods.toAuthJSON = function()
return
username: this.username,
email: this.email,
token: this.generateJWT(),
bio: this.bio,
image: this.image
;
;
mongoose.model('User', UserSchema);
node.js api express postman
node.js api express postman
edited Mar 25 at 20:38
Justin Miller
asked Mar 25 at 13:22
Justin MillerJustin Miller
14 bronze badges
14 bronze badges
The tutorial you are linking to is behind a paywall
– Josh
Mar 25 at 15:54
add a comment |
The tutorial you are linking to is behind a paywall
– Josh
Mar 25 at 15:54
The tutorial you are linking to is behind a paywall
– Josh
Mar 25 at 15:54
The tutorial you are linking to is behind a paywall
– Josh
Mar 25 at 15:54
add a comment |
1 Answer
1
active
oldest
votes
It looks like the /user route requires authentication. My guess would be that your Postman scripts don't include the required authentication headers containing the JWT
Thank you, but if i'm correct the post /users route doesn't use the auth?
– Justin Miller
Mar 25 at 16:10
You error message is complaining about a GET to /user, right?
– Josh
Mar 25 at 16:12
you are right, i posted the wrong error even though all of the request are coming over 404, i've updated my post. thank you for bringing that to my attention
– Justin Miller
Mar 25 at 16:50
not sure how your routing framework works, but have you tried /api/users instead?
– Josh
Mar 25 at 18:09
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55338802%2fthinkster-io-tutorial-section-create-an-account-using-the-register-request-in-p%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
It looks like the /user route requires authentication. My guess would be that your Postman scripts don't include the required authentication headers containing the JWT
Thank you, but if i'm correct the post /users route doesn't use the auth?
– Justin Miller
Mar 25 at 16:10
You error message is complaining about a GET to /user, right?
– Josh
Mar 25 at 16:12
you are right, i posted the wrong error even though all of the request are coming over 404, i've updated my post. thank you for bringing that to my attention
– Justin Miller
Mar 25 at 16:50
not sure how your routing framework works, but have you tried /api/users instead?
– Josh
Mar 25 at 18:09
add a comment |
It looks like the /user route requires authentication. My guess would be that your Postman scripts don't include the required authentication headers containing the JWT
Thank you, but if i'm correct the post /users route doesn't use the auth?
– Justin Miller
Mar 25 at 16:10
You error message is complaining about a GET to /user, right?
– Josh
Mar 25 at 16:12
you are right, i posted the wrong error even though all of the request are coming over 404, i've updated my post. thank you for bringing that to my attention
– Justin Miller
Mar 25 at 16:50
not sure how your routing framework works, but have you tried /api/users instead?
– Josh
Mar 25 at 18:09
add a comment |
It looks like the /user route requires authentication. My guess would be that your Postman scripts don't include the required authentication headers containing the JWT
It looks like the /user route requires authentication. My guess would be that your Postman scripts don't include the required authentication headers containing the JWT
answered Mar 25 at 15:58
JoshJosh
1,73814 silver badges30 bronze badges
1,73814 silver badges30 bronze badges
Thank you, but if i'm correct the post /users route doesn't use the auth?
– Justin Miller
Mar 25 at 16:10
You error message is complaining about a GET to /user, right?
– Josh
Mar 25 at 16:12
you are right, i posted the wrong error even though all of the request are coming over 404, i've updated my post. thank you for bringing that to my attention
– Justin Miller
Mar 25 at 16:50
not sure how your routing framework works, but have you tried /api/users instead?
– Josh
Mar 25 at 18:09
add a comment |
Thank you, but if i'm correct the post /users route doesn't use the auth?
– Justin Miller
Mar 25 at 16:10
You error message is complaining about a GET to /user, right?
– Josh
Mar 25 at 16:12
you are right, i posted the wrong error even though all of the request are coming over 404, i've updated my post. thank you for bringing that to my attention
– Justin Miller
Mar 25 at 16:50
not sure how your routing framework works, but have you tried /api/users instead?
– Josh
Mar 25 at 18:09
Thank you, but if i'm correct the post /users route doesn't use the auth?
– Justin Miller
Mar 25 at 16:10
Thank you, but if i'm correct the post /users route doesn't use the auth?
– Justin Miller
Mar 25 at 16:10
You error message is complaining about a GET to /user, right?
– Josh
Mar 25 at 16:12
You error message is complaining about a GET to /user, right?
– Josh
Mar 25 at 16:12
you are right, i posted the wrong error even though all of the request are coming over 404, i've updated my post. thank you for bringing that to my attention
– Justin Miller
Mar 25 at 16:50
you are right, i posted the wrong error even though all of the request are coming over 404, i've updated my post. thank you for bringing that to my attention
– Justin Miller
Mar 25 at 16:50
not sure how your routing framework works, but have you tried /api/users instead?
– Josh
Mar 25 at 18:09
not sure how your routing framework works, but have you tried /api/users instead?
– Josh
Mar 25 at 18:09
add a comment |
Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.
Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55338802%2fthinkster-io-tutorial-section-create-an-account-using-the-register-request-in-p%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
The tutorial you are linking to is behind a paywall
– Josh
Mar 25 at 15:54