I'm having trouble creating the Redis DB model for Passport Amazon oAuth2. I am using "redis-connect" module and I have got a running Redis local server. my redis server successsfully stores session data so the module and the server is running well. I only need help with the User variable.
Here is my code:
//create a user model
var User = new RedisStore({ host:'127.0.0.1', port:6379, prefix:'token' });
passport.serializeUser(function(user, done) {
console.log('serializeUser: ' + user._id);
done(null, user._id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user){
console.log(user);
if(!err){ done(null, user);}
else {done(err, null);}
});
});
passport.use(new AmazonStrategy({
clientID: "foo",
clientSecret: "SECRET",
callbackURL: "https://localhost/auth/amazon/callback"
},
function(accessToken, refreshToken, profile, done) {
User.findOne({ oauthID: profile.id }, function(err, user) {
if(err) { console.log(err); }
if (!err && user !== null) {
done(null, user);
} else {
var user = new User({
oauthID: profile.id,
name: profile.displayName,
created: Date.now()
});
user.save(function(err) {
if(err) {
console.log(err);
} else {
console.log("saving user ...");
done(null, user);
}
});
}
});
}
));
Also the findById function is not defined. I have no idea how... I believed it was part of the redis-connect module. Can anyone help me out here?
Related
I'm using passport js local strategy for authentication and nodejs. problem is when i try to login with wrong password, I still redirects to success page.
what i have to do
this is login strategy
const passport = require('passport')
const LocalStratery = require('passport-local').Strategy;
const User = require('../models/userAuth')
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);
});
});
passport.use('local-login', new LocalStratery({
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true
}, function(req, email, password, done) {
console.log(email)
console.log(password)
User.findOne({email: email})
.then((err, user) => {
if(err) {
return done(null, err, req.flash('unkonown', 'there was an error,
please try after sometime'))
}
if(!user) {
console.log(user)
return done(null, false, req.flash('NotExists', 'no user
exixts'))
}
if(!user.validpass(password)){
return done(null, false, req.flash('passFail', 'password not
matches'))
}
if(user) {
return done(null, user, req.flash('success', 'login success'))
}
})
.catch(err => {
throw err
})
}))
user model using mongoose
userAuth.methods.excryptPass = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(5), null)
}
userAuth.methods.validpass = (password) => {
return bcrypt.compareSync(password, this.password);
}
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?
I am using passport-local and passport-facebook strategies for authentication in sails.js. Authentication with email is working fine. But when user authenticates using facebook, I am getting this error message [Error: Failed to serialize user into session].
Then I tested serializeUser method and it turns out user param is empty in case of facebook. While I also tried to see if verifyHandler is called or not and it is not being called.
Here is my code for the facebook authentication action:
facebook: function (req, res) {
passport.authenticate('facebook', {failureRedirect: '/login', scope: ['email']}, function (err, user) {
if ((err) || (!user)) {
req.session.flash = {
errMsg: 'Email or password mismatch.'
}
return res.redirect('/login');
}
req.logIn(user, function (err) {
if (err) {
console.log(err);
res.view('500');
return;
}
res.redirect('/');
return;
});
})(req, res);
}
And this is the code of passport.js service (api/services/passport.js)
var passport = require('passport'),
LocalStrategy = require('passport-local').Strategy,
FacebookStrategy = require('passport-facebook').Strategy,
bcrypt = require('bcrypt');
var verifyHandler = function (token, tokenSecret, profile, done) {
console.log('in verifyHandler'); // this line is not being executed.
console.log(profile);
process.nextTick(function () {
User.findOne({uid: profile.id}, function (err, user) {
if (err) {
return done(err);
}
if (user) {
return done(null, user);
} else {
var data = {
provider: profile.provider,
uid: profile.id,
name: profile.displayName
};
if (profile.emails && profile.emails[0] && profile.emails[0].value) {
data.email = profile.emails[0].value;
}
User.create(data, function (err, user) {
return done(err, 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(new LocalStrategy({
usernameField: 'email',
passwordField: 'password'
},
function (email, password, done) {
User.findOne({email: email}).exec(function (err, user) {
if (err) {
return done(err);
}
if (!user) {
return done(null, false, {message: 'Unknown user ' + email});
}
bcrypt.compare(password, user.password, function (err, res) {
if (!res) return done(null, false, {message: 'Invalid Password'});
return done(null, user);
});
});
}
));
passport.use(new FacebookStrategy({
clientID: sails.config.facebook.clientID,
clientSecret: sails.config.facebook.clientSecret,
callbackURL: sails.config.facebook.callbackURL
}, verifyHandler));
And finally (config/passport.js)
var passport = require('passport'),
LocalStrategy = require('passport-local').Strategy,
FacebookStrategy = require('passport-facebook').Strategy;
module.exports = {
http: {
customMiddleware: function (app) {
app.use(passport.initialize());
app.use(passport.session());
}
}
};
Any thoughts?
Check if user.id is defined and it is string but not ObjectId().
in
passport.serializeUser(function (user, done) {
done(null, user.id);
});
first off thank you for your help. I am trying to make a call to the facebook api to gather all of my users friends.
passport.use(new FacebookStrategy({
clientID: config.fb.id,
clientSecret: config.fb.secret,
callbackURL: "http://localhost:3000/auth/facebook/callback"
},
function(accessToken, refreshToken, profile, done) {
User.findOne({
"facebook.id" : profile.id
}, function(err, user) {
if (err) {
return done(err);
}
//No user was found... so create a new user with values from Facebook (all the profile. stuff)
if (!user) {
this is the call back I am made to return the data
function viewback(err, data, user) {
if(err) {
console.log("Error: " + JSON.stringify(err));
} else {
return data;
}
}
below is where I am making the call for friends, the data variable is not getting set before the call to create the user is being completed and it is not saving the data.
var fbapi = require('facebook-api');
var client = fbapi.user(accessToken); // do not set an access token
process.nextTick(function(){
var data = client.me.friends(viewback);
});
user = new User({
name: profile.displayName,
username: profile.username,
profileUrl: profile.profileUrl,
provider: 'facebook',
token: accessToken,
//now in the future searching on User.findOne({'facebook.id': profile.id } will match because of this next line
facebook: profile._json
fb_friends: data
});
user.save(function(err) {
if (err) console.log(err);
console.log('making a new user')
return done(err, user);
});
} else {
//found user. Return
console.log('found the user')
return done(err, user);
}
});
}));
I don't receive any errors and the user saves in the DB, but without the friend data. Any help would be great. Even better would be something I could read to pick up on this concept.
How can I serialize/deserialize multiple local strategies:
I have already tried this Use multiple local strategies in PassportJS but not success.
This is my code :
passport.use('user', new LocalStrategy( function(username, password, done) {
UserSchema.findOne({ username: username }, function(err, user) {
// ...
return done(null, user);
});
}));
passport.use('admin', new LocalStrategy( function(username, password, done) {
adminSchema.findOne({ username: username }, function(err, user) {
// ...
return done(null, user);
});
}));
passport.serializeUser(function(user, done){
done(null, user.id);
});
passport.deserializeUser(function(id, done){
adminSchema.findById(id, function(err, user){
if(err) done(err);
if(user){
done(null, user);
} else {
user.findById(id, function(err, user){
if(err) done(err);
done(null, user);
})
}
});
I was working on the same problem. I took your code and changed a few things and it worked for me! Make sure to log out of one account before trying another or just use an incognito tab.
Here is the updated code I used:
passport.use('user', new LocalStrategy( function(username, password, done) {
UserSchema.findOne({ username: username }, function(err, user) {
// ...
return done(null, user);
});
}));
passport.use('admin', new LocalStrategy( function(username, password, done) {
adminSchema.findOne({ username: username }, function(err, user) {
// ...
return done(null, user);
});
}));
passport.serializeUser(function(user, done){
done(null, user.id);
});
passport.deserializeUser(function(id, done){
adminSchema.findById(id, function(err, user){
if(err) done(err);
if(user){
done(null, user);
} else {
UserSchema.findById(id, function(err, user){
if(err) done(err);
done(null, user);
})
}
});
My schema names are different so I changed them to match yours. One issue you might have is using UserSchema instead of userSchema. Try that next if it doesn't work.
Hope this helps!