The following program uses passportjs for username/password authentication. I do not what mistake am I making, but I am always redirected to the failure page, i.e back again to the login page.
var passport = require('passport')
, LocalStrategy = require('passport-local').Strategy
, express = require('express');
var app = express();
app.listen(3000);
app.use(express.static(__dirname+'/public'));
app.use(passport.initialize());
app.use(passport.session());
passport.use(new LocalStrategy(
function(username, password, done) {
console.log(username + ':username');
console.log(password + ':password');
return done(null, [{username:'foo'}]);
}
));
app.get('/login',(req,resp) => {
var options = {
root: __dirname + '/public/'
};
resp.sendFile('login.html',options);
});
app.post('/login',
passport.authenticate('local', { successRedirect: '/',failureRedirect: '/login'})
);
I am trying to understand the working of passportjs and I see that the middleware passport.use(new LocalStrategy( never gets invoked. I do not know the reason but may be it could be the root cause of failure.
So I was missing body parser module required by passportjs to parse the post request. Here is the complete code:
var passport = require('passport')
, LocalStrategy = require('passport-local').Strategy
, express = require('express')
, bodyParser = require('body-parser');
var app = express();
app.listen(3000);
app.use(express.static(__dirname+'/public'));
app.use(bodyParser.urlencoded({ extended: false }));// parse application/x-www-form-urlencoded
app.use(bodyParser.json()); // parse application/json
app.use(passport.initialize());
app.use(passport.session());
passport.use('local',new LocalStrategy(
function(username, password, done) {
console.log(username + ':username');
console.log(password + ':password');
return done(null, {username:username});
}
));
passport.serializeUser(function(user, done) {
done(null, user.username);
});
passport.deserializeUser(function(id, done) {
done(null, user);
});
app.get('/login',(req,resp) => {
var options = {
root: __dirname + '/public/'
};
resp.sendFile('login.html',options);
});
app.post('/login',
passport.authenticate('local', { successRedirect: '/',failureRedirect: '/login'})
);
Maybe passport need session try add app.use(express.session({ secret: 'keyboard cat' })); before passport config.
You must name your strategy and serialize user
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.use('local', new LocalStrategy(
function(username, password, done) {
console.log(username + ':username');
console.log(password + ':password');
return done(null, [{username:'foo'}]);
}
));
You call this strategy by name in this eg local
app.post('/login',
passport.authenticate('local', { successRedirect: '/',failureRedirect: '/login'})
);
Related
today I was trying to get a passport authentication working. The email and password is static now but I will change that later. I have a lot of debug messages but only the ones outside of the Strategy. No errors or warnings regarding passport are displayed.
I have already tried to use different body parser modes (extented = true, extented = false).
Strategy
const LocalStrategy = require('passport-local').Strategy;
module.exports = function(passport) {
passport.use(
new LocalStrategy((email, password, done) => {
console.log('Authentication started');
var user = null;
if(email == 'test#mytest.com') {
if(password == 'test') {
user = {
email
}
console.log('Authenticated')
return done(null, user);
}
}
console.log('Error')
return done(null, user, {message: 'EMail or Password was wrong'});
})
);
passport.serializeUser(function(user, done) {
done(null, user.email);
});
passport.deserializeUser(function(id, done) {
done(err, user);
});
};
app.js (contains only important parts)
const express = require('express');
const expressSession = require('express-session')
const bodyParser = require('body-parser');
const expressLayouts = require('express-ejs-layouts');
const app = express();
const https = require('https');
const http = require('http');
app.use(expressSession({ secret: 'secret' }));
// Body Parser
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());
// Passport
const passport = require('passport');
require('./config/passport')(passport);
app.use(passport.initialize());
app.use(passport.session());
// View Engine
app.set('view engine', 'ejs');
app.use(expressLayouts);
app.get('/applications', (req,res) => {
res.render('applications', {
user: req.user
});
});
app.post('/applications', (req, res, next) => {
console.log(req.body);
passport.authenticate('local', {
successRedirect: '/applications',
failureRedirect: '/',
failureFlash: false
})(req, res, next);
});
https.createServer(httpsOptions, app)
.listen(7443, () => {
console.log('HTTPS Server started on Port 7443')
});
http.createServer(app)
.listen(7080, () => {
console.log('HTTP Server started on Port 7080')
});
Make sure you are using the proper fields in your POST request. I noticed that in your strategy, you use the variables email and password. While your variable names aren't important, the fields you send in your POST request are. By default, passport-local uses the POST fields username and password. If one of these fields aren't present, the authentication will fail. You can change this to use email instead like so:
passport.use(
new LocalStrategy({
usernameField: 'email'
}, (email, password, done) => {
console.log('Authentication started');
// Your authentication strategy
})
);
Assuming you have the right POST fields, in order to use req.user in requests, you must have properly set up your passport.deserializeUser function. Testing your code, the authentication strategy is working fine for me, however I receive a reference error upon deserializeUser.
I am trying to use passportjs with the following code.
So when the user goes to http://localhost:3000, he should automatically be redirected to /hello but as it does, it redirects to /hello?failure.
I have tried to debug, look around but haven't found the issue and the solution.
const express = require('express');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const session = require('express-session');
let app = express();
app.use(session({
secret: 'mysecret',
cookie: {
secure: false
},
resave: true,
saveUninitialized: true
}
));
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
passport.use('local-login', new LocalStrategy(function (username, password, done) {
console.log(username + ' username ');
console.log(password + ' password ');
return done(null, { name: 'suhail' });
}));
passport.serializeUser(function (user, done) {
console.log(user, ' serialize ');
done(null, user.name);
});
passport.deserializeUser(function (id, done) {
console.log(id, ' deserialize ');
done(null, { name: 'suhail' });
});
app.get('/', passport.authenticate('local-login', { successRedirect: '/hello', failureRedirect: '/hello?failure' }));
app.get('/hello', (req, resp, next) => resp.send('hello').end());
app.listen(3000);
What is it that I am missing? It should go to http://localhost:3000/hello as the middleware always resolves.
Note:
- None of the middleware defined is called. It just redirects to /hello?failure when a GET request to / is made.
You are not providing username and password in your get request. Therefore the Strategycallback is never called.
Try adding this middleware in front of your routing to see what i mean:
app.use((req, res, next) => {
// fake body content for authentication
req.body = {username: 'devil', password: '666'}
next()
})
app.get('/', passport.authenticate('local-login', { successRedirect: '/hello', failureRedirect: '/hello?failure' }));
I'm new to MEAN stack and I'm trying to setup a simple social login using google passport strategy. I can successfully authenticate myself, but when calling a redirect on success, the middle ware function isLoggedIn keeps showing req.isAuthenticated() to be false. Below are code snippets. I saw that there were multiple posts on this issue but none of the answers seem to work for me. Kindly help me resolve this issue.
passport.js
var Auth = require('./auth.js');
var ubCust = require('../models/ubCust.js');
var FacebookStrategy = require('passport-facebook').Strategy;
var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
//var FacebookStrategy = require('passport-facebook').Strategy;
module.exports= function(passport){
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
ubCust.findById(id,function(err,user){
done(err, user);
})
});
passport.use(new GoogleStrategy ({
clientID: Auth.googleAuth.clientID,
clientSecret: Auth.googleAuth.clientSecret,
callbackURL : Auth.googleAuth.callbackURL
},
function(token, refreshToken, profile, done) {
// Create or update user, call done() when complete...
process.nextTick(function(){
ubCust.findOne({'google.id' : profile.id}, function(err, user) {
if (err)
return done(err);
if(user)
return done(null,user);
else
{
var newUser = new ubCust;
newUser.google.id = profile.id;
newUser.google.token = token;
newUser.google.name = profile.displayName;
newUser.google.email = profile.emails[0].value;
newUser.save(function(err){
if (err)
throw err;
return done(null,newUser);
});
console.log(profile);
}
//done(null, profile, tokens);
}); //findOne
});//nextTick
}
));
};
route(authController.js)
module.exports = function(app,passport){
app.get('/api/getprofauth',isLoggedIn,function(req,res){
console.log('In getprofile authentication api');
//console.log('req.query :',req.query);
res.send(req.user);
});
app.get('/auth/google',
passport.authenticate('google',{scope: ['email','profile']})
);
app.get('/auth/google/callback',
passport.authenticate('google', {failureRedirect: '/'}),
function(req, res) {
console.log('auth success!! ',req.isAuthenticated(),req.user);
res.redirect('/api/getprofauth');
}
);
function isLoggedIn(req,res,next) {
// if user is authenticated in the session, carry on
if (req.isAuthenticated())
{
console.log('isAuthenticated Success');
return next();
}
else{
console.log('req.user',req.user,req.isAuthenticated());
console.log('isAuthenticated Failure');
res.redirect('/');
}
// if they aren't redirect them to the home page
}//isLoggedIn
}
app.js(server)
var express = require('express');
var app = express();
var mongoose = require('mongoose');
var config = require('./config');
var passport = require('passport');
var cookieParser = require('cookie-parser');
app.use(cookieParser());
var session = require('express-session');
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,
cookie: { secure: true }
}));
var authController = require('./controllers/authController.js');
var port = process.env.PORT||3000;
app.use(express.static(__dirname+ '/public'));
app.set('view engine','ejs');
app.get('/',function(req,res){
//redirecting request to home page '/' to index page
res.redirect('/index.htm');
});
mongoose.connect(config.getDBConnectionString());
app.use(passport.initialize());
app.use(passport.session());
var pp = require('./config/passport');
pp(passport);
apiController(app);
apibike(app);
appoController(app);
authController(app,passport);
app.listen(port);
I am building user registration using nodejs and express. I am creating a new user without any passport or any authentication strategy. what I want is user should be treated as logged in once he registered successfully.
So I am building login api for user. Where user can authentic using only email field (as I am not storing any password with user). But I am not able to validate user as I am getting 'missing credential' in passport authentication.
app.js
var config = require('./config/development');
var passport = require('passport');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session');
var app = express();
//connect db
mongoose.connect(config.db);
mongoose.set('debug', config.mongoose.debug);
require('./config/passport')(passport); // pass passport for configuration
//initialize all models
var modelsPath = require('path').join(__dirname, 'models');
require('fs').readdirSync(modelsPath).forEach(function(file) {
require('./models/' + file);
});
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(expressValidator());
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(cookieParser());
/// required for passport
app.use(session({
secret: 'anystringoftext',
saveUninitialized: true,
resave: true
})); // session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
app.use(express.static(path.join(__dirname, 'public')));
require('./routes')(app, passport);
passport.js
var mongoose = require('mongoose'),
LocalStrategy = require('passport-local').Strategy,
User = require('../models/users');
module.exports = function(passport) {
// Serialize the user id to push into the session
passport.serializeUser(function(user, done) {
done(null, user.id);
});
// Deserialize the user object based on a pre-serialized token
// which is the user id
passport.deserializeUser(function(id, done) {
User.findOne({
_id: id
}, function(err, user) {
done(err, user);
});
});
// Use local strategy
passport.use(new LocalStrategy({
usernameField: 'email',
passReqToCallback : true
},
function(email, password, done) {
User.findOne({
email: email
}, function(err, user) {
if (err) {
return done(err);
} else {
return done(null, user);
}
});
}
));
return passport;
};
routes/user.js
module.exports = function(app, passport) {
app.post('/login', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (user === false) {
res.json('no user found');
} else {
res.json('login successful');
}
})(req, res, next);
});
};
Will anyone please help me to figure out what am I doing wrong here.
You're halfway there. You can use passport-local and have it only require a username field.
You can override the username and password field to use the same key.
passport.use(new LocalStrategy({
usernameField: 'email',
passwordField: 'email',
passReqToCallback : true
},
Then it only requires that you include one field in the login request.
I have some login page, as soon as the authenticated get success, in the next page, I should display Login Details.. ( ie., username and password )
I'm using Express NodeJs, Passport, connect-flash, mongoose
My prob is: I'm unable to understand how to retrieve username, password in the next rendered page..
Please someone suggest me how to achieve it. I'm not asking you code, BUT show me a way to get my output.
EDIT:
app.js
var http = require('http');
var express = require('express'),
passport = require('passport')
, LocalStrategy = require('passport-local').Strategy,
flash = require('connect-flash'),
User = require('./routes/userdao.js');
passport.use(new LocalStrategy(
function(username, password, done) {
User.findOne({ uname: username ,pwd:password}, function(err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: 'Incorrect username.' });
}
return done(null, user);
});
}
));
passport.serializeUser(function(user, done) {
done(null, user._id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
var app = express();
app.configure(function(){
app.use(express.logger('dev')); /* 'default', 'short', 'tiny', 'dev' */
app.use(express.cookieParser());
app.use(express.bodyParser());
app.use(express.session({ secret: 'mysecret' }));
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
app.engine('.html', require('ejs').__express);
app.set('view engine', 'html');
app.set('views', __dirname + '/views');
app.use(app.router);
// app.use(express.errorHandler());
}).listen(3000);
console.log('Listening on port 3000...');
app.get('/',function(req,res){
/* req.flash('info', 'Flash is back!')
res.redirect('/success');*/
res.render('home.ejs');
});
app.get('/login',function(req,res){
res.render('login.ejs');
});
app.get('/success',function(req,res){
res.render('success.ejs',{ uname : req.user.username });
});
app.post('/login',
passport.authenticate('local', { successRedirect: '/success', failureRedirect: '/login',
failureFlash: true }));
success.ejs
<%= uname %>
I'm trying to display username which I entered in the login page.. I'm getting output: undefined
please tell me what went wrong and what I need to correct?
In the most general sense, if authentication succeeds the user object you return from authenticate ends up at req.user in your downstream functions.
http://passportjs.org/guide/authenticate/
And then, assuming you are using sessions, any subsequent requests will also expose req.user based on your serializeUser/deserializeUser functions.