NodeJS passport unknown authentication strategy - javascript

I am currently working on a node js project with passport authentication.
But i get the following error message:
Error: "Unknown authentication strategy "
Here is my Code:
LocalStrategy = require('passport-local').Strategy;
var UserModel = require('../models/user');
module.exports = function(passport){
passport.serializeUser(function(user, done){
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user){
return done(err, user);
});
});
passport.use('local-signup', new LocalStrategy({
passReqToCallback: true
}, function(req, username, password, done){
process.nextTick(function(){
User.findOne({username: username}, function(err, user) {
if(err){
return done(err);
}
if(user){
return done(null, false, req.flash('signUpErr', 'The mail is taken'));
} else {
var newUser = new UserModel();
newUser.name = username;
newUser.password = newUser.generateHash(password);
newUser.save(function(err){
if(err){
throw err;
}
console.log('All Ok');
return done(null, newUser);
})
}
});
});
}));
}
Route:
//Post requests
app.post('/signup', passport.authenticate('local-signup', {
successRedirect: '/',
failureRedirect : '/signup'
}));
My model:
var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');
var UserSchema = new mongoose.Schema({
name: String,
password: String
});
UserSchema.method.generateHash = function(password){
return bcrypt.hash(password);
};
module.exports = mongoose.model('UserModel', UserSchema);
I would really need your help, thanks!

Check if you passing the strategy along with the user credentials
var credentials = {
username:"username",
password:"password",
strategy:"local"
};
$http.post('auth/signin', credentials);
Server side
function passportAuthenticate(req, res, next, strategy) {
passport.authenticate(strategy, function(err, user, info) {
if (err || !user) {
res.status(400).send(info);
} else {
next(req, res, user);
}
})(req, res, next);
}

Related

REST API new users not posting to MongoDB

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

Authentication using MongoDB

I have made a simple Node app using authentication. I am able to signup using the form but I am not able to login using the login form.
I have written the code below. Using this I can register using the signup route, but I am not able to log in. Also, I am not getting any error, I am just redirected to failure redirect path.
Here is the code I have written
var express = require('express'),
app = express(),
bodyParser = require('body-parser'),
mongoose = require('mongoose'),
User = require("./views/models/user"),
passport = require('passport'),
flash = require('connect-flash'),
morgan = require('morgan'),
cookieParser = require('cookie-parser'),
session = require('express-session'),
expressValidator = require('express-validator'),
LocalStrategy = require('passport-local').Strategy;
mongoose.connect("mongodb://localhost/travelogue");
// set up our express application
app.use(morgan('dev')); // log every request to the console
app.use(cookieParser()); // read cookies (needed for auth)
app.use(bodyParser()); // get information from html forms
// required for passport
app.use(bodyParser.urlencoded({extended :true}));
app.use(bodyParser.json());
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
app.use(require('express-session')({
secret : "Adish",
resave : false,
saveUninitialized : false,
}));
// used to serialize the user for the session
passport.serializeUser(function(user, done) {
done(null, user.id);
});
// used to deserialize the user
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
app.use(express.static('public'));
app.set("view engine","ejs");
//routes
app.get("/Login",function(req,res){
res.render("login");
});
app.get("/Signup",function(req,res){
res.render("signup");
});
app.get("/",function(req,res){
res.render("index");
});
// we will use route middleware to verify this (the isLoggedIn
function)
/*app.get('/profile', isLoggedIn, function(req, res) {
res.render('profile.ejs', {
user : req.user // get the user out of session and pass to
template
});
});*/
app.get("/logout",function(req,res){
req.logout();
res.redirect("/");
});
// Express Validator
app.use(expressValidator({
errorFormatter: function(param, msg, value) {
var namespace = param.split('.')
, root = namespace.shift()
, formParam = root;
while(namespace.length) {
formParam += '[' + namespace.shift() + ']';
}
return {
param : formParam,
msg : msg,
value : value
};
}
}));
// process the signup form
app.post('/Signup', function(req, res){
var firstname = req.body.firstname;
var lastname = req.body.lastname;
var username = req.body.username;
var email = req.body.email;
var password = req.body.password;
var gender = req.body.gender;
// 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();
var errors = req.validationErrors();
if(errors){
res.render('signup',{
errors:errors
});
} else {
var newUser = new User({
firstname: firstname,
lastname : lastname,
username : username,
email : email,
password : password,
gender : gender
});
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('/login');
}
});
passport.use(new LocalStrategy({
usernameField: 'email',
passwordField: 'password'
},
function(username, password, done) {
User.findOne({ username: username }, function(err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: 'Incorrect username.' });
}
if (!user.validPassword(password)) {
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user);
});
}
));
app.post('/login', passport.authenticate('local', {
successRedirect : '/profile', // redirect to the secure profile
section
failureRedirect : '/login', // redirect back to the signup page
if there is an error
failureFlash : true // allow flash messages
}));
app.get('/profile',function(req,res){
res.render('profile.ejs');
});
app.listen(process.env.PORT,process.env.IP,function(){
console.log("Server is running !");
});
// route middleware to make sure a user is logged in
function isLoggedIn(req, res, next) {
// if user is authenticated in the session, carry on
if (req.isAuthenticated())
return next();
// if they aren't redirect them to the home page
res.redirect('/');
}
This is the userSchema used to register (user.js):
var mongoose = require('mongoose');
var bcrypt = require('bcryptjs');
// User Schema
var UserSchema = mongoose.Schema({
firstname : String,
lastname : String,
username : {type :String, unique : true},
email : String,
password : String,
gender : String,
});
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);
if(err)
console.log(err);
});
});
};
module.exports.getUserByUsername = function(username, callback){
var query = {username: username};
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);
});
};

Getting throw er; // Unhandled 'error' event for Node & Passport

I'm trying to build a user authentication system into my Node app with Passport.js. When I try to sign up as a new user, it seems to work fine. But when I try logging in, the command prompt gives me this:
throw er; // Unhandled 'error' event
^
TypeError: done is not a function
at C:\spectray\config\passport.js:55:22
at C:\spectray\node_modules\mongoose\lib\model.js:3419:16
at C:\spectray\node_modules\kareem\index.js:212:48
at C:\spectray\node_modules\kareem\index.js:127:16
at _combinedTickCallback (internal/process/next_tick.js:67:7)
at process._tickCallback (internal/process/next_tick.js:98:9)
Here's my passport.js file:
var passport = require('passport'), LocalStrategy = require('passport-local').Strategy;
var User = require('../app/models/user');
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
passport.use('local-signup', new LocalStrategy({
passReqToCallback : true
},
function(req, email, password, done) {
process.nextTick(function() {
User.findOne({ 'local.email' : email}, function(err, user) {
if (err)
return done(err);
if (user) {
return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
} else {
var newUser = new User();
newUser.local.email = email;
newUser.local.password = newUser.generateHash(password);
newUser.save(function(err) {
if (err)
throw err;
return done(null, newUser);
});
}
});
});
}));
passport.use(new LocalStrategy({
passReqToCallback : true
},
function(username, password, done) {
User.findOne({ username: username }, function(err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: 'Incorrect username.' });
}
if (!user.validPassword(password)) {
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user);
});
}
));
And here's my server.js file:
var express = require('express');
var app = express();
var port = process.env.PORT || 8080;
var mongoose = require('mongoose');
var passport = require('passport');
var morgan = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session');
var flash = require('connect-flash');
var db = require('./config/database.js');
var favicon = require('serve-favicon');
app.use(favicon(__dirname + '/public/imgs/favicon.ico'));
mongoose.Promise = global.Promise;
mongoose.connect(db.url);
require('./config/passport');
app.use(morgan('dev'));
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.set('view engine', 'ejs');
app.use(session({ secret: 'penniesfromheaven', resave: true, saveUninitialized: true }));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
app.use(express.static(__dirname + '/public'));
require('./app/routes.js')(app, passport);
app.listen(port);
console.log('The magic happens on port ' + port);
I tried deleting my node_modules folder and running npm install, but this error still shows up. What am I doing wrong?
Because you are setting the passReqToCallback option to true in the LocalStrategy constructor, your callback function gets called with these arguments: (req, username, password, done), but your function is accepting (username, password, done), which is why the arguments are getting assigned to the wrong parameters (and thus why done isn't a function as the error message says). To fix this, try removing the passReqToCallback option, like this:
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, { message: 'Incorrect username.' });
}
if (!user.validPassword(password)) {
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user);
});
}));
Or, if you decide later that you need the req in your LocalStrategy, then add the parameter to the function, like this:
passport.use(new LocalStrategy({
passReqToCallback : true
},
function(req, username, password, done) {
User.findOne({ username: username }, function(err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: 'Incorrect username.' });
}
if (!user.validPassword(password)) {
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user);
});
}
));

Error: Unknown authentication strategy "local" (Express & Passport)

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("/");
});
}
});
});

node.js passport local strategy problems

I am new to node.js in general and passport in particular.
I have exposed a passport configuration in a file by itself like the following:
var LocalStrategy = require('passport-local').Strategy;
var User = require('../models/User');
var messages = {
100: 'Username and/or password are not correct.',
101: 'User already exists.'
};
module.exports = function (passport) {
passport.serializeUser(function (user, done) {
done(null, user._id);
});
passport.deserializeUser(function (id, done) {
User.findById(id, function (err, user) {
done(err, user);
});
});
passport.use('local-login', new LocalStrategy(function (username, password, done) {
User.findOne({ username: username }, function (err, user) {
if (err) {
return done(err);
}
if (!user) {
return done(null, false, req.flash('loginMessage', messages['100']));
}
user.comparePassword(password, function (err, isMatch) {
if (err) {
return done(err);
}
if (isMatch) {
return done(null, user);
} else {
return done(null, false, req.flash('loginMessage', messages['100']));
}
});
});
}));}
in my node routes, i am doing the following to handle the login scenario:
app.post('/login',function(req, res, next){
console.log('loggin in ')
passport.authenticate('local-login', function(err, user, info){
console.log('allo');
console.log(err);
console.log(user);
console.log(info)
});
});
however I am not getting a response; can you please clarify what I am doing wrong.
You need to return the object returned by passport.authenticate
app.post('/login',function(req, res, next){
console.log('loggin in ')
/**/return passport.authenticate('local-login', function(err, user, info){
console.log('allo');
console.log(err);
console.log(user);
console.log(info)
})(req, res, next);
});

Categories

Resources