this is my app.js
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const cors = require('cors');
const passport = require('passport');
const app = express();
app.use(cors());
//Mongodb connection
mongoose.connect("mongodb://localhost/expressWithAngular")
.then(() => {
console.log("mongodb connected");
})
//bodyparser middleware
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
//load routes
const users = require("./routes/users");
//include passport
require("./config/passport")(passport);
// use routes
app.use('/user' , users);
app.get('' ,(req,res) => {
res.send('home');
})
const port = 5000;
app.listen(port , () => {
console.log(`server is running in port ${port}`);
})
this is my user routes routes/user.js
const express = require('express');
const mongoose = require('mongoose');
const router = express.Router();
const bcrypt = require('bcryptjs');
const passport = require('passport');
//user model init
require('./../models/User');
const User = mongoose.model('users');
router.post('/login' , (req,res,next)=>{
console.log("bodyparser" ,req.body);
passport.authenticate('local',{
session: false
},function(req,res,next){
console.log(res);
})
})
module.exports = router;
this is my config/passport.js
const LocalStrategy = require('passport-local').Strategy;
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const User = mongoose.model('users');
module.exports = function(passport){
passport.use(new LocalStrategy(
{
usernameField : 'email'
},
function(email,password,done){
console.log(email);
}
))
}
- i was trying to connect my mean stack app with passport
authentication, i am able to send details to backend but i couldn't
pass the value to local strategy
- I don't know where i am missing, when i consoled the local strategy is
not called, please correct me where i am missing
I believe that you have problem in your router configuration. passport.authenticate is generating middleware for you, but in your case you have wrapped it in function so you could log input parameters and you haven't returned generated middleware to router:
router.post('/login' , (req,res,next)=>{
console.log("bodyparser" ,req.body);
passport.authenticate('local',{
session: false
},function(req,res,next){
console.log(res);
})
})
I would advise you to modify your code to work like in example in official documentation:
router.post('/login' , passport.authenticate('local',{
session: false
});
)
If you really need to log req.body just add a middleware before authentication like this:
router.post('/login' , (req, res, next) {
console.log("bodyparser" ,req.body);
next();
},
passport.authenticate('local', {session: false});
)
Related
I'm currently working on a register and login system with Express, Node, Mongoose and Passport.js and the register mostly works fine , but there's a big issue with the login system. For some reason in the method I've created passport cannot read "passport" of undefined, so something is coming up as undefined but I can't seem to figure it out.
I don't know why it's not working, any help please!!
this 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');
mongoose.connect(config.database);
mongoose.connection.on('connected', () => {
console.log('Connected to database ' + config.database);
});
mongoose.connection.on('error', (err) => {
console.log('Database error:' + err);
});
const app = express();
const users = require('./routes/users');
const port = 3000;
app.use(cors());
app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.json());
app.use(passport.initialize());
app.use(passport.session());
app.use('/users', users);
app.get('/', (req, res) => {
res.send('Invalid Endpoint');
});
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');
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'});
}
});
});
router.post('/authenticate', (req, res, next) =>{
res.send('AUTHENTICATE');
});
router.get('/profile', (req, res, next) =>{
res.send('PROFILE');
});
module.exports = router;
Your issue is with passport session. You need to use express session (remember to install in your dependencies) before it for it to work properly.
Your app.js should look like this:
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');
const session = require("express-session");
mongoose.connect(config.database);
mongoose.connection.on('connected', () => {
console.log('Connected to database ' + config.database);
});
mongoose.connection.on('error', (err) => {
console.log('Database error:' + err);
});
const app = express();
const users = require('./routes/users');
const port = 3000;
app.use(cors());
app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.json());
app.use(session({secret: "secret"});
app.use(passport.initialize());
app.use(passport.session());
app.use('/users', users);
app.get('/', (req, res) => {
res.send('Invalid Endpoint');
});
app.listen(port, () =>{
console.log('Server started on port' + port);
});
Also, keep in mind that body parser is deprecated for Express 4.16.0 or higher. It has been re-added in methods express.json() and express.urlencoded() so if your Express version falls into that category, you can change your app.js to:
const express = require('express');
const path = require('path');
const cors = require('cors');
const passport = require('passport');
const mongoose = require('mongoose');
const config = require('./config/database');
const session = require("express-session");
mongoose.connect(config.database);
mongoose.connection.on('connected', () => {
console.log('Connected to database ' + config.database);
});
mongoose.connection.on('error', (err) => {
console.log('Database error:' + err);
});
const app = express();
const users = require('./routes/users');
const port = 3000;
app.use(cors());
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(session({secret: "secret"});
app.use(passport.initialize());
app.use(passport.session());
app.use('/users', users);
app.get('/', (req, res) => {
res.send('Invalid Endpoint');
});
app.listen(port, () =>{
console.log('Server started on port' + port);
});
I suggest adding comments to your code to keep it neat as well.
In case anyone else runs into this error:
express-session deprecated undefined resave option; provide resave option
express-session deprecated undefined saveUninitialized option; provide saveUninitialized option app.
In addition to #raijin30 answer, I had to add the properties below (:
resave: true,
saveUninitialized: true
Explanation as to why, can be found at: Node JS session error: express-session deprecated.
Had the same problem and noticed that passport got updated on Septmeber 23rd. So, I decided to install the previous version via npm using
npm install --save passport#0.4.1
This solved the issue for me. Not really sure how or why it happened in the first place, but it might help you.
I created a route and controller for my sign up.
Here's my route:
const express = require("express");
const router = express.Router();
const { signup } = require("../../controllers/auth");
router.post("/signup", signup);
module.exports = router;
And here's my controller:
exports.signup = () => (req, res) => {
const { name, email, password } = req.body;
res.json({
user: { name, email, password },
});
};
Inside my server.js file I register both:
const express = require("express");
const morgan = require("morgan");
const cookieParser = require("cookie-parser");
const cors = require("cors");
const mongoose = require("mongoose");
require("dotenv").config();
// routes
const blogRoutes = require("./routes/blog");
const authRoutes = require("./routes/auth");
// app
const app = express();
// db
mongoose
.connect(process.env.DATABASE, { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => console.log("DB connected!"));
// middlewares
app.use(morgan("dev"));
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(cookieParser());
// cors
if (process.env.NODE_ENV == "development") {
app.use(cors({ origin: `${process.env.CLIENT_URL}` }));
}
// routes middleware
app.use("/api", blogRoutes);
app.use("/api", authRoutes);
// port
const port = process.env.PORT || 8000;
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
Now on my POSTMAN, I tried to put the data using POST http://localhost:8000/api/signup with the header and raw setup right.
{
"name": "SyRyan",
"email": "syryan#gmail.com",
"password": "brace1010"
}
The database is connected but the postman takes forever to load the json request back. Am I making any mistakes here? Please help!
I think that the problem is that signup is a function that returns a function, but it should be just a function that receives req & res as parameters:
exports.signup = (req, res) => {
const { name, email, password } = req.body;
res.json({
user: { name, email, password },
});
};
So I am trying to build an authentication system using passport in MERN(MongoDB, Express, React, NodeJS).
I set up everything, I connected react with NodeJS,
The problem is when I am trying to log in or register it shows me,
this error "User.findOne is not a function" in the console and I tried to fix it by looking for any
type mistakes or google it but I didn't find anything online.
Did anyone have a similar mistake and fix it or does anyone know how?
Model Code:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const ObjectId = Schema.ObjectId;
const UserSchema = new Schema ({
password: String,
email: String,
}, {
collection: 'information'
})
const User = mongoose.model('information', UserSchema);
module.exports - User;
Passport Code:
const Strategy = require('passport-local').Strategy
const mongoose = require('mongoose')
const User = require('../models/user');
const bcrypt = require('bcryptjs')
const salt = bcrypt.genSaltSync(10);
const SignupStrategy = new Strategy ({ passReqToCallback:true, usernameField: 'email' }, function(req, email, password, done){
User.findOne({email: req.body.email}).lean().exec((err, user) => {
if (err) {
return done(err, null);
}
if (user) {
return done("User already exist", null);
}
const encryptedPassword = bcrypt.hashSync(password, salt);
let newUser = new User({
email,
password: encryptedPassword
})
newUser.save((error, inserted) => {
if (error) {
return done(error, null);
}
delete inserted.password;
return done(null, inserted);
})
})
});
module.exports = SignupStrategy;
Node server:
const createError = require('http-errors');
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');
const passport = require('./passport/');
const PORT = process.env.PORT || 8080;
const mongoose = require('mongoose');
//I have used password in mongo I just did <password> for security reasons.
const mongoString = mongoose.connect('mongodb+srv://herpryth:<password>#nowyourguest-ga5vy.gcp.mongodb.net/users?retryWrites=true&w=majority', {useNewUrlParser: true})
const indexRouter = require('./routes/index');
const usersRouter = require('./routes/users');
const app = express();
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use('/', indexRouter);
app.use('/authentication', usersRouter);
app.use(passport.initialize());
app.use(passport.session());
app.listen(process.env.PORT || 8080, process.env.IP || '0.0.0.0');
module.exports = app
Route:
const express = require('express');
const app = express.Router();
const passport = require('../passport')
app.post('/signup', (req, res, next) =>{
passport.authenticate('local-signup', function(error, user, info){
if (error) {
return res.status(500).json({
message: error || 'Something happend',
error : error.message || "Server error"
});
}
return res.json(user);
})(req, res, next);
})
app.post('/signin', function(req, res, next){
passport.authenticate('local-signin', function(error, user, info){
if (error) {
return res.status(500).json({
message: error || 'Something happend',
error : error.message || "Server error"
});
}
return res.json(user);
})(req, res, next);
})
module.exports = app;
React server:
const createError = require('http-errors');
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');
const passport = require('./passport/');
const PORT = process.env.PORT || 8080;
const mongoose = require('mongoose');
const mongoString = mongoose.connect('mongodb+srv://herpryth:XFXGJakc18wBJLIk#nowyourguest-ga5vy.gcp.mongodb.net/users?retryWrites=true&w=majority', {useNewUrlParser: true})
const indexRouter = require('./routes/index');
const usersRouter = require('./routes/users');
const app = express();
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use('/', indexRouter);
app.use('/authentication', usersRouter);
app.use(passport.initialize());
app.use(passport.session());
app.listen(process.env.PORT || 8080, process.env.IP || '0.0.0.0');
module.exports = app
Does anyone know how to fix this problem?
There is just a simple mistake in your code
replace with
module.exports = User
to
module.exports - User
I'm new to express and node js, I recently learned how to write API for express but at the end, I get some sort of problem which not resolved by me after several tries. I could not get a response on localhost:8080/users
src/routes/users.js
const { Router } = require("express");
const router = Router();
const getUsers = (req, res) =>
res.send(Object.values(req.context.models.users));
const getUser = (req, res) =>
res.send(req.context.models.users[req.params.userId]);
router.get("/users/", getUsers);
router.get("/users/:userId", getUser);
module.exports = router;
src/routes/index.js
const user = require("./user");
const message = require("./message");
module.exports = {
user,
message
};
src/index.js
const express = require("express");
const app = express();
// Custom Modules
const routes = require("./routes");
const models = require("./models");
// Application-Level Middleware Starts
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use((req, res, next) => {
req.context = {
models,
me: models.users[1]
};
console.log(req.context.models.users);
next();
});
// Used Routes
app.use("/users", routes.user);
app.use("/messages", routes.message);
// App Listning to HTTPS Module
app.listen(process.env.PORT);
You need to fix your endpoints in users.js:
router.get("/", getUsers);
router.get("/:userId", getUser);
The reason is because of app.use("/users", routes.user); in your index.js, where the endpoint for users is set. If you leave /users/ in users.js it would be localhost:8080/users/users/. Same problem might be with /messages.
Update: I have downloaded express-4.x-local-example and can't seem to get it working either. Is there something that I'm missing?
I'm trying to set a local strategy for passport but it's not being fired. After entering the credentials, the page redirects to failureRedirect.
app.js
const express = require('express')
, app = express()
, mainRouter = require('./controllers/mainRouter');
mainRouter(app);
mainRouter.js
const bodyParser = require('body-parser')
, passport = require('passport')
, passportConfig = require('../config/passport');
passportConfig(passport);
module.exports = (app) => {
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(passport.initialize());
app.use(passport.session());
app.post('/login', passport.authenticate(('local'), {
successRedirect: '/',
failureRedirect: 'login/',
})
);
}
passport.js
const LocalStrategy = require('passport-local').Strategy;
module.exports = (passport) => {
passport.use(new LocalStrategy({usernameField: 'email'},
(email, password, done) => {
console.log('This message is not being logged.');
})
);
}
Your not actually calling the strategy in your mainRouter.js file.
Before the app.post, add passport.use(passportConfig);