I am new to building REST API's, and I am trying to enter new user information into a collection called 'Users', however, when I submit the information I get Cannot POST /register
Below is my code
server.js
require('dotenv').config()
const express = require('express')
const app = express()
const mongoose = require('mongoose')
const expressValidator = require('express-validator')
mongoose.connect(process.env.DATABASE_URL, { useNewUrlParser: true , useUnifiedTopology: true })
const db = mongoose.connection
db.on('error', (error) => console.error(error))
db.once('open', () => console.log('Connected to Database'))
app.use(express.json())
const articlesRouter = require('./routes/articles')
app.use('/articles', articlesRouter)
const userRouter = require('./routes/users')
app.use('/register', userRouter)
app.set('view-engine', 'ejs')
app.use(express.urlencoded({ extended: false }))
app.get('/', (req, res) => {
res.render('index.ejs')
})
app.get('/login', (req, res) => {
res.render('login.ejs')
})
app.post('/login', (req, res) => {
})
app.get('/register', (req, res) => {
res.render('register.ejs')
})
app.listen(3000, () => console.log('Server Started'))
Users model
const mongoose = require('mongoose')
const bcrypt = require('bcrypt')
var userSchema = new mongoose.Schema({
firstName: String,
lastName: String,
email: String,
password: String,
permissionLevel: Number,
created: Date},
{ collection: 'Users'});
module.exports = mongoose.model('Users', userSchema);
module.exports.createUser = function(newUser, callback){
bcrypt.genSalt(10, function(err, salt) {
bcrypt.hash(newUser.password, salt, function(err, hash) {
newUser.password = hash;
newUser.save(callback);
});
});
}
module.exports.getUserByEmail = function(email, callback){
var query = {email: email};
User.findOne(query, callback);
}
module.exports.getUserById = function(id, callback){
user.findById(id, callback);
}
module.exports.comparePassword = function(candidatePassword, hash, callback) {
bcrypt.compare(candidatePassword, hash, function(err, isMatch){
if(err) throw err;
callback(null, isMatch)
});
}
users routes
const express = require('express')
const router = express.Router()
const Users = require('../models/users')
const passport = require('passport')
const LocalStrategy = require('passport-local').Strategy
//Register Page - GET
router.get('/register', (req, res) => {
res.render('register.hbs', {
pageTitle: 'register'
});
});
//Login Page - GET
router.get('/login', (req, res) => {
res.render('login.hbs', {
pageTitle: 'login'
});
});
//Register - POST
router.post('/', (req, res) => {
var firstName = req.body.firstName;
var lastName = req.body.lastName;
var email = req.body.email;
var password = req.body.password;
//validations
req.checkBody('firstName', 'Your First Name is Required').notEmpty();
req.checkBody('lastName', 'Your Last Name is Required').notEmpty();
req.checkBody('email', 'A valid email is required').isEmail();
req.checkBody('password', 'An Account Passowrd Is Required').notEmpty();
var errors = req.validationErrors();
if (errors) {
res.render('register', {
errors:errors
});
} else {
var newUser = new newUser({
firstName: firstName,
lastName: lastName,
email: email,
password: password,
});
User.createUser(newUser, function(err, user) {
if(err) throw(err);
console.log(user);
});
req.flash('success_message', "You are now registered!");
res.redirect('/login');
}
});
passport.use(new LocalStrategy({
email: 'email'
},
function(email, password, done){
Users.getUserByEmail(email, function(err, Users){
if(err) throw err;
if(!Users){
return done(null, false, {message: 'Unknown Email Address'});
}
Users.comparePassword(password, user.password, function(err, ismatch){
if(err) throw err;
if(ismatch){
return done (null, user);
} else {
return done(null, false, {message: 'Invalid Passowrd'});
}
});
});
}));
passport.serializeUser(function(user, done){
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
Users.getUserByID(id, function(err, user) {
done(err, user)
});
});
router.post('/login', passport.authenticate('local', {
successRedirect: '/dashboard',
failureRedirect: '/login',
successFlash: 'Welcome',
failureFlash: 'Invalid Email or Passowrd!'
}), function(req, res) {
res.redirect('/');
});
router.get('/logout', function(req, res) {
req.logout();
req.flash('Success_message', 'You are now logged out!')
res.redirect('/');
});
module.exports = router
I suspect the conflict is between the router /register and the my 'Users' collection. I'm just unable to pinpoint what the issue could be.
Any help would be greatly appreciated
Your userRouter is mounted on /users (from your code: app.use('/users', userRouter), meaning that all the routes you declared in the router are prefixed by /users).
Try calling POST /users/register.
You're using users routes file at /users route, so when you declare /register route in users routes file it become /users/register please send your REST API request to /users/register endpoint
Related
when I pass name: req.user.name to my ejs file it gives me undefined, Can you help me with that please. let me know if you need more information if you need. I have tried a lot of ways but non of then have worked. thanks for the help.
Error:
Cannot read property 'name' of undefined when i call it in index.js
app.js
const express = require("express");
const expressLayouts = require('express-ejs-layouts');
const mongoose = require("mongoose");
const app = express();
const passport = require('passport');
const flash = require('connect-flash');
const session = require('express-session');
const PORT = process.env.PORT || 3000;
const nodemailer = require("nodemailer");
const bodyParser = require("body-parser");
var exphbs = require('express-handlebars');
app.engine('handlebars', exphbs());
app.set('view engine', 'handlebars');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static("public"));
app.get("/home", function(req, res) {
res.sendFile(__dirname + "/index.html")
})
app.get("/login", function(req, res) {
res.sendFile(__dirname + "/login.ejs")
})
app.get("/signup", function(req, res) {
res.sendFile(__dirname + "/register.html")
})
app.get("/payment", function(req, res) {
res.sendFile(__dirname + "/payment.html")
})
app.get("/companyInfo", function(req, res) {
res.sendFile(__dirname + "/companyInfo.html")
})
app.get("/FAQ", function(req, res) {
res.sendFile(__dirname + "/Faq.html")
})
app.get("/contactUs", function(req, res) {
res.sendFile(__dirname + "/contactUs.html")
})
app.post("/contactUs", function(req, res) {
const output = `
<h1>You have a new feedback</h1>
<ul>
<h3>Full Name: ${req.body.name}</h3>
<h3>Full Email: ${req.body.email}</h3>
<h3>Order Number: ${req.body.orderNumber}</h3>
</ul>
<h1>The Subject</h3>
<h3>${req.body.subject}</h1>
`;
var transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: "sziacustomer#gmail.com",
pass: "Sziaszia12"
}
});
var mailOptions = {
from: req.body.email,
to: 'TEAMSZIA#GMAIL.COM',
subject: 'Costumers Email',
html: output
};
transporter.sendMail(mailOptions, function(error, info) {
if (error) {
console.log(error);
res.sendFile(__dirname + ("/failed.html"), { msg: "email sent" });
} else {
console.log('Email sent: ' + info.response);
res.sendFile(__dirname + ("/success.html"), { msg: "email sent" });
}
});
});
//bodyparser
app.use(express.urlencoded({ extended: false }))
const db = require("./config/keys").mongoURI;
require('./config/passport')(passport);
// Express session
app.use(
session({
secret: 'secret',
resave: true,
saveUninitialized: true
})
);
// Passport middleware
app.use(passport.initialize());
app.use(passport.session());
// connect flash
app.use(flash());
// Global variables
app.use(function(req, res, next) {
res.locals.success_msg = req.flash('success_msg');
res.locals.error_msg = req.flash('error_msg');
res.locals.error = req.flash('error');
next();
});
//connect mangodb using mongoose
mongoose.connect(db, { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => console.log("mongoo bd connected"))
.catch(() => console.log(err));
//ejs
app.use(expressLayouts);
app.set('view engine', 'ejs');
app.use("/", require("./routes/index"));
app.use("/dashboard", require("./routes/index"));
app.use("/users", require("./routes/users"))
app.listen(PORT, console.log(`we are live on ${PORT}`));
*
index.js*
const express = require("express");
const router = express.Router();
const mongoose = require("mongoose");
const bcrypt = require('bcryptjs');
const User = require('../models/User');
const users = require("./users");
const LocalStrategy = require('passport-local').Strategy;
const { ensureAuthenticated } = require("../config/auth")
router.get("/", users, (req, res) =>
res.render("welcome", {
login: req.isAuthenticated(),
name: req.user.name //undefined
}))
user.js
const express = require("express");
const router = express.Router();
const bcrypt = require("bcryptjs");
const User = require("../models/User");
const passport = require("passport")
router.get("/login", (req, res) => res.render("login"));
router.get("/register", (req, res) => res.render("register"));
router.post('/register', (req, res) => {
const { name, email, password, password2 } = req.body;
let errors = [];
if (!name || !email || !password || !password2) {
errors.push({ msg: 'Please enter all fields' });
}
if (password != password2) {
errors.push({ msg: 'Passwords do not match' });
}
if (password.length < 6) {
errors.push({ msg: 'Password must be at least 6 characters' });
}
if (errors.length > 0) {
res.render('register', {
errors,
name,
email,
password,
password2
});
} else {
User.findOne({ email: email }).then(user => {
if (user) {
errors.push({ msg: 'Email already exists' });
res.render('register', {
errors,
name,
email,
password,
password2
});
} else {
const newUser = new User({
name,
email,
password
});
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(newUser.password, salt, (err, hash) => {
if (err) throw err;
newUser.password = hash;
newUser
.save()
.then(user => {
req.flash(
'success_msg',
'You are now registered and can log in'
);
res.redirect('/users/login');
})
.catch(err => console.log(err));
});
});
}
});
}
});
// Login
router.post('/login', (req, res, next) => {
passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/users/login',
failureFlash: true,
})(req, res, next);
});
// Logout
router.get('/logout', (req, res) => {
req.logout();
req.flash('success_msg', 'You are logged out');
res.redirect('/users/login');
});
module.exports = router;
passport.js
const LocalStrategy = require('passport-local').Strategy;
const bcrypt = require('bcryptjs');
// Load User model
const User = require('../models/User');
module.exports = function(passport) {
passport.use(
new LocalStrategy({ usernameField: 'email' }, (email, password, done) => {
// Match user
User.findOne({
email: email
}).then(user => {
if (!user) {
return done(null, false, { message: 'That email is not registered' });
}
// Match password
bcrypt.compare(password, user.password, (err, isMatch) => {
if (err) throw err;
if (isMatch) {
return done(null, user);
} else {
return done(null, false, { message: 'Password incorrect' });
}
});
});
})
);
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
}
auth.js
module.exports = {
ensureAuthenticated: function(req, res, next) {
if (req.isAuthenticated()) {
return next();
}
req.flash('error_msg', 'Please log in to view that resource');
res.redirect('/users/login');
},
forwardAuthenticated: function(req, res, next) {
if (!req.isAuthenticated()) {
return next();
}
res.redirect('/');
}
}
Due to my lack of experience, as well as taking bits and pieces of code from different sources, I cannot pinpoint why I am getting the Reference Error: User is not defined. The error occurs when I input/submit a new user's information, so the DB never populates, and I get the below error.
Error
ReferenceError: users is not defined
at /Desktop/REST API/server.js:50:17
at Layer.handle [as handle_request] (/Desktop/REST API/node_modules/express/lib/router/layer.js:95:5)
at next (/REST API/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/REST API/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/Desktop/REST API/node_modules/express/lib/router/layer.js:95:5)
at /Desktop/REST API/node_modules/express/lib/router/index.js:281:22
at Function.process_params (/Desktop/REST API/node_modules/express/lib/router/index.js:335:12)
at next (/Desktop/REST API/node_modules/express/lib/router/index.js:275:10)
at /Desktop/REST API/node_modules/body-parser/lib/read.js:130:5
at invokeCallback (/Desktop/REST API/node_modules/raw-body/index.js:224:16)
at done (/Desktop/REST API/node_modules/raw-body/index.js:213:7)
at IncomingMessage.onEnd (/Desktop/REST API/node_modules/raw-body/index.js:273:7)
at IncomingMessage.emit (events.js:327:22)
at endReadableNT (_stream_readable.js:1201:12)
at processTicksAndRejections (internal/process/task_queues.js:84:21)
Here is my code
routes users.js
const express = require('express')
const router = express.Router()
const Users = require('../models/users')
router.get('/register', (req, res) => {
res.render('register.hbs', {
pageTitle: 'register'
});
});
router.get('/login', (req, res) => {
res.render('login.hbs', {
pageTitle: 'login'
});
});
router.post('/register', (req, res) => {
var firstName = req.body.firstName;
var lastName = req.body.lastName;
var email = req.body.email;
var password = req.body.password;
//validations
req.checkBody('firstName', 'Your First Name is Required').notEmpty();
req.checkBody('lastName', 'Your Last Name is Required').notEmpty();
req.checkBody('email', 'A valide email is required').notEmpty();
req.checkBody('password', 'An Account Passowrd Is Required').notEmpty();
var errors = req.validationErrors();
if (errors) {
res.render('register', {
errors:errors
});
} else {
var newUser = new newUser({
firstName: firstName,
lastName: lastName,
email: email,
password: password,
});
newUser.createUser(newUser, function(err, user) {
if(err) throw(err);
console.log(user);
});
req.flash('success_message', "You are now registered!");
res.redirect('/login');
}
});
passport.use(new LocalStrategy({
email: 'email'
},
function(email, password, done){
User.getUserByEmail(email, function(err, user){
if(err) throw err;
if(!user){
return done(null, false {message: 'Unknown Email Address'});
}
User.comparePassword(password, user.password, function(err, ismatch){
if(err) throw err:
if(ismatch){
return done (null, user);
} else {
return done(null, false, {message: 'Invalid Passowrd'});
}
});
});
}));
passport.serializeUser(function(user, done){
done(null, user.id);
});
passport.deserializeUser(funtion(id, done){
User.getUserByID(id, function(err, user) {
done(err, user)
});
});
router.post('/login', passport.authenticate('local', {
successRedirect: '/dashboard',
failureRedirect: '/login',
successFlash: 'Welcome'
failureFlash: 'Invalid Email or Passowrd!'
}), function(req, res) {
res.redirect('/');
});
router.get('/logout', function(req, res) {
req.logout();
req.flash('Success_message', 'You are now logged out!')
res.redirect('/');
});
module.exports = router
model: users.js
const mongoose = require('mongoose')
const bcrypt = require('bcrypt')
var articlesSchema = new mongoose.Schema({
firstName: String,
lastName: String,
email: String,
password: String,
permissionLevel: Number,
created: Date},
{ collection: 'Users'});
const User = module.exports = mongoose.model('Users', userSchema);
module.exports.createUser = function(newUser, callback){
bcrypt.genSalt(10, function(err, salt) {
bcrypt.hash(newUser.password, salt, function(err, hash) {
newUser.password = hash;
newUser.save(callback);
});
});
}
module.exports.getUserByEmail = function(email, callback){
var query = {email: email};
User.findOne(query, callback);
}
module.exports.getUserById = function(id, callback){
user.findById(id, callback);
}
module.exports.comparePassword = function(candidatePassword, hash, callback) {
bcrypt.compare(candidatePassword, hash, function(err, isMatch){
if(err) throw err;
callback(null, isMatch)
});
}
Finally my server.js which is where i believe the issue(s) reside:
require('dotenv').config()
const express = require('express')
const app = express()
const mongoose = require('mongoose')
const bcrypt = require('bcrypt')
mongoose.connect(process.env.DATABASE_URL, { useNewUrlParser: true , useUnifiedTopology: true })
const db = mongoose.connection
db.on('error', (error) => console.error(error))
db.once('open', () => console.log('Connected to Database'))
app.use(express.json())
const articlesRouter = require('./routes/articles')
app.use('/articles', articlesRouter)
app.set('view-engine', 'ejs')
app.use(express.urlencoded({ extended: false }))
app.get('/', (req, res) => {
res.render('index.ejs')
})
app.get('/login', (req, res) => {
res.render('login.ejs')
})
app.post('/login', (req, res) => {
})
app.get('/register', (req, res) => {
res.render('register.ejs')
})
app.post('/register',(req, res) => {
try{
const hashedPassword = bcrypt.hash(req.body.password, 10)
users.push({
firstName:req.body.firstName,
lastName:req.body.lastName,
email: req.body.email,
password: hashedPassword
})
res.redirect('/login')
} catch {
res.redirect('/register')
}
console.log(users)
})
app.listen(3000, () => console.log('Server Started'))
Any help, It would be greatly appreciated.
You are trying to do users.push in server.js L50. There is no users array, and thus the error.
if you want to create a user (assuming because the route is /register), you need to import the User model and create the user. But I see you are already doing that in your user routes. You just need to connect those routes with your server.js and remove this code IMO.
I am trying to code a mean authentication app. Right now i can create user in mongodb via postman but when i try to authenticate it,if it has wrong username or password it gives proper feedback,wrong password etc, but if it matches correct username and password on database, server shutdowns, it doesnt gives any feedback on postman and it gives the following error on server terminal:
(node:11262) DeprecationWarning: Mongoose: mpromise (mongoose's
default promise library) is deprecated, plug in your own promise
library instead: http://mongoosejs.com/docs/promises.html
/home/cagdas/Desktop/basictest/node_modules/jsonwebtoken/sign.js:90
throw err;
^
Error: Expected object
at validate
(/home/cagdas/Desktop/basictest/node_modules/jsonwebtoken
/sign.js:35:11) at Object.module.exports [as sign]
(/home/cagdas/Desktop/basictest/node_modules/jsonwebtoken
/sign.js:101:7) at User.comparePassword
(/home/cagdas/Desktop/basictest/routes/users.js:40:26)
at bcrypt.compare (/home/cagdas/Desktop/basictest/models/user.js:52:6)
at
/home/cagdas/Desktop/basictest/node_modules/bcryptjs/dist
/bcrypt.js:297:21
at /home/cagdas/Desktop/basictest/node_modules
/bcryptjs/dist/bcrypt.js:1353:21
at Immediate.next (/home/cagdas/Desktop/basictest/node_modules
/bcryptjs/dist/bcrypt.js:1233:21)
at runCallback (timers.js:672:20)
at tryOnImmediate (timers.js:645:5)
at processImmediate [as _immediateCallback] (timers.js:617:5)
This is my code:
app.js:
const express = require('express') ;
const path = require('path');
const bodyParser = require('body-parser');
const cors = require('cors');
const passport = require('passport');
const mongoose = require('mongoose');
const config = require('./config/database');
// Connect to Database
mongoose.connect(config.database, { useMongoClient: true });
// On Connection
mongoose.connection.on('connected', () => {
console.log('Connected to database '+config.database);
});
// On Error
mongoose.connection.on('error', (err) =>{
console.log('Database error: '+err);
});
const app = express();
const users = require('./routes/users');
// Port Number
const port = 3000;
// Cors Middleware
app.use(cors());
// Set Static Folder
app.use(express.static(path.join(__dirname, 'public')));
// Body Parser Middleware
app.use(bodyParser.json());
// Passport Middleware
app.use(passport.initialize());
app.use(passport.session());
require('./config/passport')(passport);
app.use('/users', users);
// Index Route
app.get('/', (req, res) => {
res.send('Invalid Endpoint');
});
// Start Server
app.listen(port, () => {
console.log('Server started on port '+port);
});
users.js:
const express = require('express');
const router = express.Router();
const passport = require('passport');
const jwt = require('jsonwebtoken');
const User = require('../models/user');
const config = require('../config/database');
// Register
router.post('/register', (req, res, next) => {
let newUser = new User({
name: req.body.name,
email: req.body.email,
username: req.body.username,
password: req.body.password
});
User.addUser(newUser, (err, user) =>{
if(err){
res.json({success: false, msg:'Failed to register user'});
} else {
res.json({success: true, msg:'User registered'});
}
});
});
// Authenticate
router.post('/authenticate', (req, res, next) => {
const username = req.body.username;
const password = req.body.password;
User.getUserByUsername(username, (err, user) => {
if(err) throw err;
if(!user){
return res.json({success: false, msg: 'User not found'});
}
User.comparePassword(password, user.password, (err, isMatch) => {
if(err) throw err;
if(isMatch){
const token = jwt.sign(user, config.secret, {
expiresIn: 86400 // 1 day
});
res.json({
success: true,
token: 'JWT ' +token,
user: {
id: user._id,
name: user.name,
username: user.username,
email: user.email
}
});
} else {
return res.json({success: false, msg: 'Wrong Password'});
}
});
})
});
// Profile
router.get('/profile', (req, res, next) => {
res.send('PROFILE');
});
module.exports = router;
database.js:
module.exports = {
database: 'mongodb://localhost:27017/basictest',
secret: '123456789'
}
user.js:
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const config =require('../config/database');
// User Schema
const UserSchema = mongoose.Schema({
name: {
type: String
},
email: {
type: String,
required: true
},
username: {
type: String,
required: true
},
password: {
type: String,
required: true
}
});
const User = module.exports = mongoose.model('User', UserSchema);
module.exports.getUserById = function(id, callback){
User.findById(id, callback);
}
module.exports.getUserByUsername = function(username, callback){
const query = {username: username}
User.findOne(query, callback);
}
module.exports.addUser = function(newUser, callback){
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(newUser.password, salt, (err, hash) => {
if(err) throw err;
newUser.password = hash;
newUser.save(callback);
});
});
}
module.exports.comparePassword = function(candidatePassword, hash,
callback){
bcrypt.compare(candidatePassword, hash, (err, isMatch) => {
if(err) throw err;
callback(null, isMatch);
});
}
passport.js
const JwtStrategy = require('passport-jwt').Strategy;
const ExtractJwt = require('passport-jwt').ExtractJwt;
const User = require('../models/user');
const config = require('../config/database');
module.exports = function(passport){
let opts = {};
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderWithScheme('jwt');
opts.secretOrKey = config.secret;
passport.use(new JwtStrategy(opts, (jwt_payload, done) => {
User.getUserById(jwt_payload._id, (err, user) => {
if(err){
return done (err, false);
}
if(user){
return done(null, user);
} else {
return done(null, false);
}
});
}));
}
Solution - not user only { data: user }
const token = jwt.sign({data: user}, config.secret, {
expiresIn: 604800 // 1 week
});
Got the same error for a while and I suggest that you recreate a new object user (without the hashed password for security reason) and insert it into the sign function.
let restrictedUser = {
id: user._id,
username: user.username,
name: user.name,
email: user.email
}
const token = jwt.sign(restrictedUser, config.secret, {
expiresIn: "7d"
})
Hope this will help.
Not sure about this, But you can try this
"npm remove mongoose"
Then
"npm install mongoose#4.10.8 --save"
Hope it will help you..
Thanks...
I'm trying to use passport authentication within express app.
router.get('/signup', (req ,res) => {
res.render('signup');
});
router.post('/signup', function(req, res, next) {
var username = req.body.username;
var password = req.body.password;
User.findOne({ username: username }, function(err, user) {
if(err) { return next(err); }
if(user) {
req.flash('error', 'User already exists');
return res.redirect('/signup');
}
var newUser = new User({
username: username,
password: password
});
newUser.save(next);
});
}, passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/signup',
failureFlash: true
}));
Every time I try to sign up test user, it works but it shows me an error like this:
Error: Unknown authentication strategy "local"
Can you advise me something.
It looks like you haven't setup Passport to use your passport-local strategy yet.
You'll need to import it, instantiate it, and then instruct Passport to use it. Here's an example:
var LocalStrategy = require('passport-local').Strategy;
passport.use(new LocalStrategy(
function(username, password, done) {
User.findOne({ username: username }, function (err, user) {
if (err) { return done(err); }
if (!user) { return done(null, false); }
if (!user.verifyPassword(password)) { return done(null, false); }
return done(null, user);
});
}
));
router.post('/signup', function(req, res, next) {
var username = req.body.username;
var password = req.body.password;
User.findOne({ username: username }, function(err, user) {
if(err) { return next(err); }
if(user) {
req.flash('error', 'User already exists');
return res.redirect('/signup');
}
var newUser = new User({
username: username,
password: password
});
newUser.save(next);
passport.authenticate('local', { failureRedirect: '/signup' }),
function(req, res) {
res.redirect('/');
});
});
});
Please read the documentation here for that plugin.
Also, here's an example app using that auth strategy.
Try using a callback function after local instead of passing an object. Something like this:
router.post("/register", function(req, res){
var newUser = new User({username: req.body.username});
User.register(newUser, req.body.password, function(err, user){
if(err){
req.flash("error", err.message); //such as the username is taken or no username entered etc.
res.redirect("/register");
} else {
passport.authenticate("local")(req, res, function(){
res.redirect("/");
});
}
});
});
I am creating multiplayer game, where I have login system as well. I want to update my user's rating using db.collection.update(), but it is not working. There is no error, just when I write username of my player It says "Unknown User". I write it in my app.js. Besides app.js I have 3 more files for my user.
My app.js
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var flash = require('connect-flash');
var fs = require('fs');
var session = require('express-session');
var mongo = require('mongodb');
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/loginapp');
var db = mongoose.connection;
var routes = require('./routes/index');
var users = require('./routes/users');
var User = require('./models/users');
// Init App
var app = express();
var server = require("http").Server(app);
// BodyParser Middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
// Express Session
app.use(session({
secret: 'secret',
saveUninitialized: true,
resave: true
}));
User.getUserByRating(rating, function(err)
{
if(err) throw err;
});
});
}));
// Connect Flash
app.use(flash());
// Global Vars
app.use(function (req, res, next) {
res.locals.success_msg = req.flash('success_msg');
res.locals.error_msg = req.flash('error_msg');
res.locals.error = req.flash('error');
res.locals.user = req.user || null;
console.log(req.user);
next();
});
app.use('/', routes);
app.use('/users', users);
User.collection.update(
{ username: "example2" },
{
name: "qq",
rating: 1
}
)
My users.js
var express = require('express');
var router = express.Router();
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var User = require('../models/users');
// Register
router.get('/register', function(req, res){
res.render('register');
});
// Login
router.get('/login', function(req, res){
res.render('login');
});
//Register User
router.post('/register', function(req, res){
var name = req.body.name;
var email = req.body.email;
var username = req.body.username;
var password = req.body.password;
var password2 = req.body.password2;
var rating = req.body.rating;
// Validation
req.checkBody('email', 'Email is required').notEmpty();
req.checkBody('email', 'Email is not valid').isEmail();
req.checkBody('username', 'Username is required').notEmpty();
req.checkBody('password', 'Password is required').notEmpty();
req.checkBody('password2', 'Passwords do not match').equals(req.body.password);
var errors = req.validationErrors();
if(errors)
{
res.render('register',{
errors:errors
});
} else
{
var newUser = new User({
name: name,
email:email,
username: username,
password: password,
rating: 1000
});
User.createUser(newUser, function(err, user){
if(err) throw err;
console.log(user);
});
req.flash('success_msg', 'You are registered and can now login');
res.redirect('/users/login');
}
});
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.getUserById(id, function(err, user) {
done(err, user);
});
});
router.post('/login',
passport.authenticate('local', {successRedirect:'/', failureRedirect:'/users/login',failureFlash: true}),
function(req, res) {
res.redirect('/');
});
router.get('/logout', function(req, res){
req.logout();
req.flash('success_msg', 'You are logged out');
res.redirect('/users/login');
});
module.exports = router;
My model(again users.js, but in another folder)
var mongoose = require('mongoose');
var bcrypt = require('bcryptjs');
var UserSchema = mongoose.Schema({
username: {
type: String,
index:true
},
password: {
type: String
},
email: {
type: String
},
name: {
type: String
},
rating:
{
type: Number
}
});
var User = module.exports = mongoose.model('User', UserSchema);
module.exports.createUser = function(newUser, callback){
bcrypt.genSalt(10, function(err, salt) {
bcrypt.hash(newUser.password, salt, function(err, hash) {
newUser.password = hash;
newUser.save(callback);
});
});
}
module.exports.getUserByUsername = function(username, callback){
var query = {username: username};
User.findOne(query, callback);
}
module.exports.getUserByRating = function(rating, callback){
User.findOne({ rating : rating}, callback);
}
module.exports.getUserById = function(id, callback){
User.findById(id, callback);
}
module.exports.comparePassword = function(candidatePassword, hash, callback){
bcrypt.compare(candidatePassword, hash, function(err, isMatch) {
if(err) throw err;
callback(null, isMatch);
});
}
My index.js
var express = require('express');
var router = express.Router();
// Get Homepage
router.get('/', ensureAuthenticated, function(req, res){
res.render('index');
});
function ensureAuthenticated(req, res, next){
if(req.isAuthenticated()){
return next();
} else {
//req.flash('error_msg','You are not logged in');
res.redirect('/users/login');
}
}
module.exports = router;
Thanks a lot in advance. I will be grateful for any help.
Your update code uses raw mongo interface:
User.collection.update(
{ username: "example2" },
{
name: "qq",
rating: 1
}
)
This code replace your document as whole(all missed fields like password and etc will be lost).
You may be want to use followed: {$set: {name: 'qq', rating: 1}}
Or use mongoose interface:
User.update({username: 'example2'}, {name: 'qq', rating: 1});
It will add $set part automatically, if you don't specify safe = false in your model.
Check actual database state before you start to do anything in your code. There are some users incosistent with your model schema, and may be no user with example2 name.