I'm trying to authenticate users on my website and I got this error
Unknown authentication strategy 'local-login'
I've tried changing the name of the strategy, also I've read other threads in SO but didn't find a solution.
// Passport
module.exports = function(passport) {
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
connection.query('SELECT * FROM `users` WHERE `id` = ' + connection.escape(id), function(err, rows) {
done(err, rows[0]);
});
});
passport.use('local-login', new LocalStrategy({
usernameField : 'username',
passwordField : 'password'
},
function(req, username, password, done) {
connection.query('SELECT * FROM `users` WHERE `username` = ' + connection.escape(username), function(err, rows) {
if(err)
return done(err);
if(!rows.length) {
return done(null, false, req.flash('loginMessage', 'Invalid username or password. Please try again.'));
}
if(!(rows[0].password == password))
return done(null, false, req.flash('loginMessage', 'Invalid username or password. Please try again.'));
return done(null, rows[0]);
});
}));
}
// Express Router
app.use(sessionMiddleware);
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
app.use('/static', express.static('./static'));
app.post('/login/auth', passport.authenticate('local-login', {
successRedirect: '/dashboard',
failureRedirect: '/',
failureFlash: true
}));
First check your installation with:
npm install passport passport-local --save
Then import passport like below:
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
before your app.use() methods:
...
..
app.use(passport.initialize());
app.use(passport.session());
Then use it as follows. (No need to give 'local-login' as a first argument)
passport.use(new LocalStrategy({
usernameField : 'username',
passwordField : 'password'
}, (req, username, password, done) => {
// Your logic here...
...
..
}));
}
Finally in your router:
app.post('/login/auth', passport.authenticate('local', {
successRedirect: '/dashboard',
failureRedirect: '/',
failureFlash: true }),
function(req, res) {
res.redirect('/');
});
More info:
passport-local
Related
I'm trying to create an application that utilizes a registration and login functionality. I have completed the registration portion where all the information (Email and Password) is successfully passed and saved into a MySQL database.
Problem: My issue now is that when I put in any existing credential and email, the application will hang and refuse to redirect the user to a new page. On the bottom of my browser, it will say "Waiting for localhost...". If I leave the page up for too long, it'll eventually lead to an error page with the words "This page isn’t working. localhost didn’t send any data. ERR_EMPTY_RESPONSE".
I tried console logging for any errors but was unable to identify any causes/errors. I did ensure that the information I inputted is properly being compared to the values in the database table and that the redirection to the page is functioning. I also tried rewriting my code in multiple ways but ended up encountering the same issue.
Below is my passport.js file:
var LocalStrategy = require('passport-local').Strategy;
// Load User model
const User = require('../models/User');
// Reference: http://www.passportjs.org/docs/
module.exports = function (passport) {
passport.use(
new LocalStrategy({ usernameField: 'email' }, (email, password, done) => {
// Match user
User.findOne({ which: { email: email } })
.then(user => {
// Check if Email exists in database
if (!user) {
return done(null, false, {
message: "Email is not registered."
});
}
// Check if password matches the one found in the database (To Do: Encrypt this later!)
if (password != user.password) {
return done(null, false, { message: 'Password is incorrect.' });
} else {
return done(null, user);
}
})
.catch(err => console.log(err));
})
);
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser(function (id, done) {
// Find by Primary Key
User.findByPk(id, function (err, user) {
console.log(user);
done(err, user);
});
});
}
Below is my app.js (server) file:
var express = require('express')
var expressLayouts = require('express-ejs-layouts');
var flash = require('connect-flash');
var session = require('express-session');
var passport = require('passport');
var app = express();
// Embedded JavaScript (EJS)
app.use(expressLayouts);
app.set('view engine', 'ejs');
// Express Session
app.use(session({
secret: 'secret',
resave: false,
saveUninitialized: false
}));
// Bodyparser
app.use(express.urlencoded({ extended: false }));
// Passport
app.use(passport.initialize());
app.use(passport.session());
require('./config/passport')(passport);
// Connect flash for notification messages
app.use(flash());
// Global Variables to define specific notification messages
app.use((req, res, next) => {
// Notification for Registration Page
res.locals.success_msg = req.flash('success_msg')
res.locals.error_msg = req.flash('error_msg');
// Notification for Passport Login Verification
res.locals.error = req.flash('error');
next();
});
// Routes
app.use('/', require('./routes/index'));
// Login/Register Endpoints routes (ex. /users/login)
app.use('/users', require('./routes/users'));
// Image
//app.use(express.static('./public'));
var port = process.env.PORT || 8026;
app.listen(port);
console.log('Server Running');
console.log("Port: " + port);
Below is my function to handle the login and redirection:
router.post('/login', (req, res, next) => {
console.log(req.body);
passport.authenticate('local', {
successRedirect: '/dashboard',
failureRedirect: '/users/login',
failureFlash: true
})(req, res, next);
});
Please let me know if you need any other information. Thank you!
I think this could be a problem. On passport.use , if an error occurred, you are not returning anything.
passport.use(
new LocalStrategy({ usernameField: 'email' }, (email, password, done) => {
// Match user
User.findOne({ which: { email: email } })
.then(user => {
// Check if Email exists in database
if (!user) {
return done(null, false, {
message: "Email is not registered."
});
}
// Check if password matches the one found in the database (To Do: Encrypt this later!)
if (password != user.password) {
return done(null, false, { message: 'Password is incorrect.' });
} else {
return done(null, user);
}
})
.catch(err =>{
console.log(err));
return done(null, false, { message: 'Internal Server error.' });
}
})
Fixed the hanging issue. It was indeed something wrong with the way I wrote passport.js as the code works more for MongoDB rather than MySQL.
Here is the new working passport.js:
module.exports = function(passport) {
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
connection.query("select * from users where id = "+id,function(err,rows){
done(err, rows[0]);
});
});
passport.use(new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true // allows pass back of entire request to the callback
},
function(req, email, password, done) { // callback with email and password from form
// Match User
connection.query("SELECT * FROM `users` WHERE `email` = '" + email + "'",function(err,rows){
if (err)
return done(err);
// Check if Email exists in database
if (!rows.length) {
return done(null, false, { message: 'Email is not registered' });
}
// Check if password matches the one found in the database (To Do: Encrypt this later!)
if (!( rows[0].password == password))
return done(null, false, { message: 'Password is incorrect.' });
// All is well, return successful user
return done(null, rows[0]);
});
}));
};
The problem is when I want pass object to view. I got a message user is undefined. The object is defined after if statement is Match and in serializeUser function. I do not know why I lose this object in route to lobby.
Here I post the route code.
var express = require('express');
var router = express.Router();
var User = require('../models/user');
var Facebook = require('../models/facebook');
var passport = require('passport')
var LocalStrategy = require('passport-local').Strategy;
var FacebookStrategy = require('passport-facebook').Strategy;
router.get('/lobby', function(req, res){
console.log("User req "+req.user);// here I got the message user undefined and I do not know why
res.render('lobby',{ user:req.user});
// res.render('lobby');
});
router.get('/logout',function(req, res){
req.logout();
req.flash('success_msg', 'You have been logged out');
res.redirect('/');
});
function ensureAuthenticated(req, res, next){
if(req.isAuthenticated()){
return next();
}else{
res.redirect('/');
}
}
router.post('/login', passport.authenticate('local', {
successRedirect : '/users/lobby',
failureRedirect : '/',
failureFlash : true
}));
//Passport strategy
passport.serializeUser(function(user, done) {
console.log("serizlize "+user); //here I got object user and it is defined
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.getUserById(id, function(err, user) {
done(err, user);
});
});
passport.use(new LocalStrategy(
function(username, password, done) {
User.getUserByUsername(username, function(err, user){
if(err) throw err;
if(!user){
return done(null, false, {message: 'wrong data'});
}
User.comparePassword(password, user.password, function(err, isMatch){
if(err) throw err;
if(isMatch){
return done(null, user);
}else{
return done(null, false,{message: 'wrong data'});
}
});
});
}));
module.exports = router;
enter link description here
*******Edit*****
Problem solved. I just red that you have to initalize express session before passport session. That works for me.
In your server file (my is app.js)
//express session
app.use(session({
secret: 'yoursecrethere',
saveUninitialized: true,
resave: false
}));
//Passport init
app.use(passport.initialize());
app.use(passport.session());
trying first time node with passport for signing to app and can't get any error in command.
after too much load it responds:
No data received
ERR_EMPTY_RESPONSE
can't find any solution for this error.
routes
loginRouter.route('/login')
.get(loginController.getLogin)
.post(loginController.postLogin);
postlogin function :
var postLogin = function(req, res, next){
passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/auth/login',
failureFlash : true
});
};
passport.js
var passport = require('passport');
var localStrategy = require('passport-local').Strategy;
var bcrypt = require('bcrypt-nodejs');
var User = require('../app/models/model')().User;
module.exports = function(){
passport.use('local',new localStrategy({
usernameField: 'username',
passwordField: 'password',
passReqToCallback : true
},
function (username, password, done){
User.findOne({
where: {
username: username
}
}).then(function(user){
if(!user) {
console.log(user);
done(null, false, req.flash('invalid credentials try again'));
} else if (!bcrypt.compareSync(password, user.password)) {
done(null, false, req.flash('invalid credentials try again'));
} else {
done(null, user);
}
});
}));
passport.serializeUser(function (user,done) {
done(null, user.id);
});
passport.deserializeUser(function (id, done){
User.findOne({where: {id: id}}).then(function(user){
done(null, user);
});
});
};
app.js
var express = require('express'),
session = require('express-session'),
cookieParser = require('cookie-parser'),
bodyParser = require('body-parser'),
passport = require('passport'),
flash = require('express-flash'),
app = express(),
port = 80;
app.use(express.static(__dirname + '/public'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded( { extended: true } ));
app.use(cookieParser());
app.use(session({
secret: 'lirary',
cookie: {
maxage: 1200000
},
resave: true,
saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
require('./config/passport')();
app.set('views','./resources/views');
app.set('view engine','ejs');
require(__dirname + '/app/routes/routes')(app);
app.listen(port,function(err){
console.log('server running on : '+ port)
if (err) {
throw err;
};
});
Just little change in my route and solved this now.
loginRouter.post('/login',
function (req, res, next) {
console.log(User.validate());
next();
},
passport.authenticate('local',{
successRedirect: '/dashboard',
failureRedirect: '/auth/login',
failureFlash : true
}
));
My passport middleware is not working. When I call passport.authenticate() on a route to confirm the user is authenticated, I am redirected to the failure page. The login route however works as expected, and I am redirected successfully to the correct page, where the failure middleware redirect is called and I am sent back to the login page.
I have a Passport strategy like so:
module.exports = function(){
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy
var User = require('../models/user');
// 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.getUserById(id, function(err, user) {
done(err, user);
});
});
passport.use(new LocalStrategy({
usernameField: "email",
passwordField: "password"
}, function(email, password, done){
User.getUserByEmail(email, function(err, user){
if(err) throw err;
if(!user){
console.log('unknown user');
return done(null, false, {message: 'Email not recognised, please try again'});
}
User.comparePassword(password, user.password, function(err, isMatch){
if(err) throw err;
if(isMatch){
return done(null, user);
} else {
console.log('Invalid password');
return done(null, false, { message: 'Password not recognised, please try again' });
}
});
});
}));
};
Logging in is fine using:
router.post('/user/login',
passport.authenticate('local', {
successRedirect: '/clients',
failureRedirect: '/user/login',
failureFlash: true
}
));
My '/clients' route is like so, where the authentication fails and redirects incorrectly back to the login page:
router.get('/clients',
passport.authenticate("local", {
failureRedirect: "/user/login",
failureFlash: "not verified"
}), function(req, res, next) {
res.locals.client = null;
Client.find({})
.select("name")
.select("_id")
.exec(function(err, clients){
res.render('client/views/clients', {
title: 'Clients',
clients: clients
});
});
});
Server passport initialization like so:
//passport
app.use(passport.initialize());
app.use(passport.session());
app.use(bodyParser.urlencoded({ extended: false }));
require("./user/services/passport")(passport);
What am I doing wrong?
As you have used failureRedirect: '/user/login' . It will redirect you to the login page. If you want to redirect it to someother page change the failureRedirect value to that corresponding route.
Im using passport for some admin authentication but the redirect seems to not be calling me function. As a result all that gets printed on login is [object Object]
My code:
Routes
app.get('/admin', isLoggedIn, Routes.admin);
app.get('/login', Routes.adminLogin);
app.post('/login', passport.authenticate('local-login', {
successRedirect : '/admin',
failureRedirect : '/login'
}));
Passport setup
var LocalStrategy = require('passport-local').Strategy;
passport.serializeUser(function(user,done){
done(null, user._id);
});
passport.deserializeUser(function(id, done){
user.getCollection().findById(id)
.on('success', function(doc){done(doc)});
});
passport.use('local-login', new LocalStrategy({
usernameField : 'username',
passwordField : 'password',
passReqToCallback : true
}, function(req,username,password,done){
user.getName(username)
.on('success', function(doc){
if(doc == null || doc.password != password) {return done(null, false, "Invalid password");}
return done(null, doc);
})
.on('error', function(err){return done(err);});
}));
};
Admin route :
var adminRoute = exports.adminRoute = function(req,res){
console.log(" ADMIN PAGE");
res.render('admin.jade');
};
#robertklep was right, passing null as the first argument in done inside deserializeUser worked.
passport.deserializeUser(function(id, done){
user.getCollection().findById(id)
.on('success', function(doc){done(null,doc)});
});