Facebook strategy with sapper and polka - passport.js

I need to make a connection with polka (not Express) and using a passport-facebook strategy. On my serverjs:
var app = polka();
passport.serializeUser(function(user, cb){
return cb(null, profile);
});
passport.deserializeUser(function(obj, cb){
return cb(null, obj);
});
passport.use(new Strategy({
clientID: *****,
clientSecret: '******',
callbackURL: 'http://localhost:3000/login/facebook/callback',
//campo opzionale, specifico gli oggetti del profilo che voglio tornato
profile: ['id', 'displayName']
},
function(accessToken, refreshToken, profile, done) {
//Check the DB to find a User with the profile.id
User.findOne({ uid: profile.id }, function(err, user) {
if(err) {
console.log(err); // handle errors!
}
if (user) {
console.log("find user!", user);
done(null, user); //Login if User already exists
} else { //else create a new User
user = new User({
uid: profile.id, //pass in the id and displayName params from Facebook
name: profile.displayName
});
user.save(function(err) { //Save User if there are no errors else redirect to login.
if(err) {
console.log(err); // handle errors!
} else {
console.log("saving user ...");
done(null, user);
console.log("user", user);
}
});
}
});
}
));
app
//va sempre messo prima di passport.session
.use(require('express-session')({ secret: 'keyboard cat', resave: true, saveUninitialized: true }))
.use(passport.initialize())
.use(passport.session())
//definisco le rotte
//rotta di login
.get('/login/facebook',
passport.authenticate('facebook')
)
//callback
.get('/login/facebook/callback',
//da confermare se รจ supportato il fialureRedirect
//passport.authenticate('facebook', {failureRedirect: '/'}),
passport.authenticate('facebook', {failureRedirect: '/'}),
function(req, res){
res.writeHead(302, {
'Location': '/admin/menu',
'content-type': 'document'
});
res.end();
}
)
.use(
compression({ threshold: 0 }),
sirv('static', { dev }),
formData.parse(options),
formData.format(),
//formData.stream(),
formData.union(),
json(),
sapper.middleware()
)
When i make the login the console shows also that i'm already logged in (it created also a object on the mongodbclient and it's also finded), but the problem is that redirect me on some url with
http://localhost:3000/login/facebook/callback?code=AQBBJIV61HxahPCtWBgMR23OMpU8MXfxDcD3BeRDTUw2rK5FvTnXq5n...
with a message "profile is not defined"
and on the console i have this on pending

On serializeUser you return profile that is never declared you have to use:
passport.serializeUser(function(user, cb){
return cb(null, user);
});

Related

passport google auth: connect-flash not working

I'm trying to flash a message when someone try to login with gmail but gmail is not found in database.... everything works fine but if there is no gmail account in database then it should return a flash message but flash not work! I've searched a lot on this topic but everyone post about passport-local...
here is my code:
--middlewares
app.use(session({
resave: false,
saveUninitialized: true,
secret: "a87ds34cN5070AS%ASasyasaad"
}));
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
--passport codes
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(user, done) {
done(null, user);
});
passport.use(new GoogleStrategy({
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: process.env.GOOGLE_CALLBACK_URI
},
function(req, accessToken, refreshToken, profile, cb){
// check if this email exist on database
db.get("SELECT * FROM users WHERE gmail=?", [profile._json.email], (error, user) => {
if(error){
console.log("there is an error!");
return cb(error, false);
}
if(user){
/* if the email is exist but user fullname field is empty then retrive these data and update this user */
if(profile.displayName != user.full_name){
db.run("UPDATE users SET full_name=? WHERE gmail=?", [profile.displayName, user.gmail], (error, done) => {
if(error){
console.log("fname error: "+error);
}
});
}
/* if the email is exist but profile avatar is empty then retrive profile avatar url from gmail and update this user */
if(profile._json.picture.split("=")[0] != user.picture){
const profile_pic = profile._json.picture.split("=")[0];
db.run("UPDATE users SET picture=? WHERE gmail=?", [profile_pic, user.gmail], (error, done) => {
if(error){
console.log("picture error: "+error);
}
});
}
return cb(error, user);
}else{
// if the email isn't exist then show this flash msg
return cb(null, false, req.flash("flash_msg", "You don't have any permission to access this area!"));
}
});
}
));
--login & callback route
app.get("/login", (req, res) => {
res.render("login.html");
});
app.get("/auth/google", passport.authenticate('google', {scope: ['profile', 'email']}));
app.get("/auth/google/callback",
passport.authenticate('google', {
successRedirect: "/",
failureRedirect: '/login',
successFlash: true,
failureFlash: true
}),
function(req, res) {
res.redirect("/");
});

Github oAuth with PassportJS not authenticated

I'm trying to use passportJS to authenticate with the github-strategy. I've previously used passportJS with success, but not with the github-strategy, though I don't figure it should be much different. /viewData is the route in which I'm testing for authentication.
The strategy authenticates successfully and puts the data in the DB and when I serialize and deserialize the user data is in fact there. The problem comes when I try to check in any route after if the req.isAuthenticated() or even if req.session.passport.user exists and it returns false and undefined respectively. The weird thing the same check in app.js after I've redirected through /testAuth the authentication logs correctly with the true and id#. So I feel like its some issue with express-session or the passport integration with that that's breaking it, but I can't find it. I've been on this for a long time so hopefully someone can help me.
app.use(cookieParser('test'));
app.use(session({
secret: 'test',
resave: false,
saveUninitialized: true
}));
//pasport setup
app.use(passport.initialize());
app.use(passport.session());
// Passport init
passport.use(new GithubStrategy({
clientID: config.github.clientID,
clientSecret: config.github.clientSecret,
callbackURL: config.github.callbackURL },
function(accessToken, refreshToken, profile, done) {
User.findOne({ oauthID: profile.id }, function(err, user) {
if(err) {
console.log(err); // handle errors!
}
if (!err && user !== null) {
done(null, user);
} else {
user = new User({
oauthID: profile.id,
name: profile.displayName,
created: Date.now()
});
user.save(function(err) {
if(err) {
console.log(err); // handle errors!
} else {
console.log("saving user ...");
done(null, user);
}
});
}
});
}
));
// test authentication
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) { return next(); }
console.log("Not Authenticated", req.user);
res.redirect('/');
}
app.get('/testAuth', ensureAuthenticated, function(req, res){
User.findById(req.session.passport.user, function(err, user) {
if(err) {
console.log(err); // handle errors
} else {
res.redirect('/viewData');
}
});
});
//auth pages
app.get('/auth/github',
passport.authenticate('github'),
function(req, res){});
app.get('/auth/github/callback',
passport.authenticate('github', { failureRedirect: '/' }),
function(req, res) {
res.redirect('/testAuth');
});
// serialize and deserialize for session
passport.serializeUser(function(user, done) {
console.log('serializeUser: ' + user);
done(null, user._id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user){
console.log('deserializeUser: ' + user);
if(!err) done(null, user);
else done(err, null);
});
});
So this is a weird one, but I was fixing something else that was weird and in doing so solved this problem. I just moved my
app.use('/', index);
app.use('/viewData', viewData);
To below all the passport code and it works now.

Passport req.isAuthenticated() doesn't work

I'm using express-session and passport to authenticate.
Here's my module :
(updated)
passport.use(new LocalStrategy(
function(username, password, done) {
LamAdmin.findOne({ email: username }, function (err, user) {
if (err) { return done(err); }
if (!user) { return done(null, false, { message: 'Incorrect username' }); }
if (!comparePassword(user.password, password)) { return done(null, false, { message: 'Incorrect password' }); }
return done(null, user);
});
}
));
router.post('/login', passport.authenticate('local',{
successRedirect: '/p/dashboard',
failureRedirect: '/p',
failureFlash: true
}));
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
LamAdmin.findById(id, function (err, user) {
done(err, user);
});
});
function checkAuth(req,res,next) {
if (req.isAuthenticated()) {
next();
} else {
res.redirect('/p');
}
}
// //DOES NOT WORK WITH CHECKAUTH MIDDLEWARE
// router.get('/dashboard',(req,res,next)=> {
// res.render('dashboard');
// });
router.get('/dashboard',checkAuth,(req,res,next)=> {
res.render('dashboard');
});
checkAuth is my middleware and idk why it always returns false.
This is passport and session configs in app.js :
//sessions
app.use(session({
secret: 'secret',
saveUninitialized: true,
resave: true,
cookie: { secure: false } // Remember to set this
}));
//passport
app.use(passport.initialize());
app.use(passport.session());
Is there anything wrong with my checkAuth middleware ?
Or my redirect to Dashboard view?
Thanks in advance!
When you call passport.authenticate() method, it uses a strategy to authenticate the user. If you have the user information stored in a local DB, then you can use the Local Strategy that will use username and password to authenticate. So in your app.js add the following:
const LocalStrategy = require('passport-local').Strategy;
passport.use(new LocalStrategy(
function(username, password, done) {
/* Change this to fetch user info from your db
User.findOne({ username: username }, function (err, user) {
if (err) { return done(err); }
if (!user) { return done(null, false); }
if (!comparePasswords(user.password, password)) { return done(null, false); }
return done(null, user);
});
*/
}
));
When the user is authenticated, serializeUser() method is called with the user object returned from the above method passed as an argument and express appends the value returned to the current user session in req.session.passport.user
passport.serializeUser(function(user, done) {
done(null, user.id);
});
On each subsequent request, when isAuthenticated() method is called, passport checks if some value is present in req.session.passport.user. If user information is present, it calls the deserializeUser() method which appends the user information to the request and can be accessed via req.user
passport.deserializeUser(function(id, done) {
// Replace it with your db
User.findById(id, function (err, user) {
done(err, user);
});
});

passportjs deserializeUser nothing happen after call

am using nodejs and express with passportJS to auth my users with session (very important to use session in my case)
basically, i have a dashboard and I want to auth each request using isLoggedIn middleware
after the user logged in, the function (deserializeUser) get running and run the findById but nothing happened after that !!!
below my code
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
// required for passport
app.use(session({ secret: 'anything' }));
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser(function(user, done) {
console.log("serializeUser =>"+user);
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
console.log("Deaire ==>"+id);
models.User.findById(id, function(err, user) {
if(user)
return done(false,user);
return done(false,false);
});
});
passport.use(new UniqueTokenStrategy({
session: true},
function (token, done) {
models.User.findOne({where: {token: token}}).then(function (user) {
models.userHasRoles.findOne({
where: {
userId: user.id
}
}).then(function (hasRoles) {
if (!hasRoles) {
return done(null, false);
}
return done(null, user);
});
})
}
));
passport.use('local',new LocalStrategy({
usernameField: 'phone_number',
passwordField: 'pin',
session: true,
passReqToCallback : true
},
function(req,phone_number, pin, done) {
console.log("Inside local str");
models.PhoneVerification.findOne({ where: {phoneNumber: phone_number, pinCode:pin}}).then(function (phoneVerification) {
if(phoneVerification==null){
models.configuration.findOne({
where:{name :"default pin"}
}).then(function (configuration) {
if(configuration.detail==pin){
}else {
return done(null, false, {message: "Couldn't login"});
}
})
}
models.User.findOne({where: {phoneNumber: phone_number}}).then(function (user) {
if(user == null){
models.User.create({
phoneNumber: phone_number,
token: randtoken.generate(32)
}).then(function (user) {
return done(null, user);
});
}else {
user.update({token: randtoken.generate(32)}).then(function () {
return done(null, user);
});
}
});
})
}
));
so till now everthing is good , i can check if am not logged in , but if i am really logged in then the code get idle there
here is my middleware to check the session
function isLoggedIn(req, res, next) {
console.log("first auth");
// if user is authenticated in the session, carry on
if (req.isAuthenticated()) {
return next();
}
so when am trying to check iof am logged in or not i get the following from console
Deaire ==>17152 Executing (default): SELECT id, firstName,
lastName, phoneNumber, photo, token, deviceToken, osInfo,
actualLat, actualLng, cityId, countryId, status,
createdAt, updatedAt FROM users AS User WHERE User.id =
17152;

Error with Facebook redirect URL on login/register using passport on a node.js (MEAN stack) application

I am implementing the Facebook login and register functions to my application, and can reach facebook for the user to enter their information, but can't make the callback work. I have input the code below into passport.js (obviously x'ing out our information):
passport.use(new FacebookStrategy({
clientID: "xxxxxxxxxxxxxx",
clientSecret: "xxxxxxxxxxxxxxxxxxx",
callbackURL: "https://xxxxxxxxxxxxxxxx/auth/facebook/callback/",
enableProof: false,
profileFields: ['id', 'displayName', 'photos']
},
function (accessToken, refreshToken, profile, done) {
process.nextTick(function () {
User.findOne({facebookId: profile.id}, function (err, user) {
if (err) {
return done(err);
}
if (user) {
return done(null, user);
} else {
var data = {
facebookId: profile.id,
f_name: profile.first_name,
l_name: profile.last_name,
username: profile.email
};
if (profile.emails && profile.emails[0] && profile.emails[0].value) {
data.username = profile.emails[0].value;
}
User.create(data, function (err, user) {
return done(err, user);
});
}
});
});
}));
passport.serializeUser(function(user, callback) {
callback(null, user._id);
});
passport.deserializeUser(function(id, done) {
User.findById({
_id: id
}, function(err, user) {
callback(err, user);
});
});
passport.use(new LocalStrategy(
function (username, password, done) {
console.log(username);
console.log(password);
User.findOne({ 'username': username }, function (err, user) {
// if (err) { return done(err); }
if (!user) {
return done(null, false, { message: 'Incorrect email.' });
}
if (!user.validPassword(password)) {
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user);
});
}
));
The following callback URL has been included in index.js:
router.get('/auth/facebook', passport.authenticate('facebook', {
scope: 'email' }));
router.get('/auth/facebook/callback',
passport.authenticate('facebook', {
successRedirect : '/user/#/home',
failureRedirect : '/'
}));
I am able to make the application direct to the Facebook login page onClick, but once the user enters their email and password into facebook, the application is unable to reload on redirect and get the person to our homepage. The redirect begins to happen, but hits an error once it tries to load our application. Could we be utilizing one of the redirect fields incorrectly? As a side note, what should we set as a valid OAuth Redirect URI on the facebook developer application page?

Resources