使用 Node 的 Passport JS 的 Facebook 身份验证失败
Facebook authentication with Passport JS using Node fails
我在成功登录 Facebook 后遇到 Facebook Strategy 失败的问题。我正在使用 Passport Local 和 Passport Facebook,但彼此独立,这是我共享的代码。
passport.use(new FacebookStrategy({
clientID: 'XYZId',
clientSecret: 'XYZSecret',
callbackURL: "/auth/facebook/callback"
},
function(accessToken, refreshToken, profile, done) {
console.log(profile);
userDetails = profile;
return done();
}
));
app.get('/auth/facebook', passport.authenticate('facebook'));
app.get('/auth/facebook/callback',
passport.authenticate('facebook', {
failureRedirect: '/login' }),
function(req, res) {
console.log("req");
console.log(userDetails);
console.log("End of Req");
res.redirect('/');
});
这段代码有什么问题吗?此外,对于本地策略,我做了一些修改,效果非常好。
// config/passport.js
// load all the things we need
var LocalStrategy = require('passport-local').Strategy;
// load up the user model
var mysql = require('mysql');
var bcrypt = require('bcrypt-nodejs');
var dbconfig = require('./database');
var connection = mysql.createConnection(dbconfig.connection);
connection.query('USE ' + dbconfig.database);
// expose this function to our app using module.exports
module.exports = function(passport) {
// =========================================================================
// passport session setup ==================================================
// =========================================================================
// required for persistent login sessions
// passport needs ability to serialize and unserialize users out of session
// 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) {
connection.query("SELECT * FROM users WHERE id = ? ",[id], function(err, rows){
done(err, rows[0]);
});
});
// =========================================================================
// LOCAL SIGNUP ============================================================
// =========================================================================
// we are using named strategies since we have one for login and one for signup
// by default, if there was no name, it would just be called 'local'
passport.use(
'local-signup',
new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'username',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, username, password, done) {
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
connection.query("SELECT * FROM users WHERE username = ?",[username], function(err, rows) {
if (err)
return done(err);
if (rows.length) {
return done(null, false, req.flash('signupMessage', 'That username is already taken.'));
} else {
// if there is no user with that username
// create the user
console.log(req.body);
var newUserMysql = {
uname: req.body.uname,
username: username,
userphone: req.body.userphone,
password: bcrypt.hashSync(password, null, null) // use the generateHash function in our user model
};
var insertQuery = "INSERT INTO users ( uname, username, password, userphone ) values (?,?,?,?)";
console.log(insertQuery);
connection.query(insertQuery,[newUserMysql.uname, newUserMysql.username, newUserMysql.password, newUserMysql.userphone],function(err, rows) {
newUserMysql.id = rows.insertId;
return done(null, newUserMysql);
});
}
});
})
);
// =========================================================================
// LOCAL LOGIN =============================================================
// =========================================================================
// we are using named strategies since we have one for login and one for signup
// by default, if there was no name, it would just be called 'local'
passport.use(
'local-login',
new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'username',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, username, password, done) { // callback with email and password from our form
connection.query("SELECT * FROM users WHERE username = ?",[username], function(err, rows){
if (err)
return done(err);
if (!rows.length) {
return done(null, false, req.flash('loginMessage', 'No user found.')); // req.flash is the way to set flashdata using connect-flash
}
// if the user is found but the password is wrong
if (!bcrypt.compareSync(password, rows[0].password))
return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.')); // create the loginMessage and save it to session as flashdata
// all is well, return successful user
return done(null, rows[0]);
});
})
);
};
控制台日志:
您没有在会话中存储授权的 Facebook 用户。您只需在 FacebookStrategy 的实现中调用不带参数的函数 done()
。首先,您应该将 fb 用户存储在您的数据库中,或者 select 如果存在则调用函数完成(接收第一个参数作为错误,第二个作为用户对象)。 here's docs
我在成功登录 Facebook 后遇到 Facebook Strategy 失败的问题。我正在使用 Passport Local 和 Passport Facebook,但彼此独立,这是我共享的代码。
passport.use(new FacebookStrategy({
clientID: 'XYZId',
clientSecret: 'XYZSecret',
callbackURL: "/auth/facebook/callback"
},
function(accessToken, refreshToken, profile, done) {
console.log(profile);
userDetails = profile;
return done();
}
));
app.get('/auth/facebook', passport.authenticate('facebook'));
app.get('/auth/facebook/callback',
passport.authenticate('facebook', {
failureRedirect: '/login' }),
function(req, res) {
console.log("req");
console.log(userDetails);
console.log("End of Req");
res.redirect('/');
});
这段代码有什么问题吗?此外,对于本地策略,我做了一些修改,效果非常好。
// config/passport.js
// load all the things we need
var LocalStrategy = require('passport-local').Strategy;
// load up the user model
var mysql = require('mysql');
var bcrypt = require('bcrypt-nodejs');
var dbconfig = require('./database');
var connection = mysql.createConnection(dbconfig.connection);
connection.query('USE ' + dbconfig.database);
// expose this function to our app using module.exports
module.exports = function(passport) {
// =========================================================================
// passport session setup ==================================================
// =========================================================================
// required for persistent login sessions
// passport needs ability to serialize and unserialize users out of session
// 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) {
connection.query("SELECT * FROM users WHERE id = ? ",[id], function(err, rows){
done(err, rows[0]);
});
});
// =========================================================================
// LOCAL SIGNUP ============================================================
// =========================================================================
// we are using named strategies since we have one for login and one for signup
// by default, if there was no name, it would just be called 'local'
passport.use(
'local-signup',
new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'username',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, username, password, done) {
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
connection.query("SELECT * FROM users WHERE username = ?",[username], function(err, rows) {
if (err)
return done(err);
if (rows.length) {
return done(null, false, req.flash('signupMessage', 'That username is already taken.'));
} else {
// if there is no user with that username
// create the user
console.log(req.body);
var newUserMysql = {
uname: req.body.uname,
username: username,
userphone: req.body.userphone,
password: bcrypt.hashSync(password, null, null) // use the generateHash function in our user model
};
var insertQuery = "INSERT INTO users ( uname, username, password, userphone ) values (?,?,?,?)";
console.log(insertQuery);
connection.query(insertQuery,[newUserMysql.uname, newUserMysql.username, newUserMysql.password, newUserMysql.userphone],function(err, rows) {
newUserMysql.id = rows.insertId;
return done(null, newUserMysql);
});
}
});
})
);
// =========================================================================
// LOCAL LOGIN =============================================================
// =========================================================================
// we are using named strategies since we have one for login and one for signup
// by default, if there was no name, it would just be called 'local'
passport.use(
'local-login',
new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'username',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, username, password, done) { // callback with email and password from our form
connection.query("SELECT * FROM users WHERE username = ?",[username], function(err, rows){
if (err)
return done(err);
if (!rows.length) {
return done(null, false, req.flash('loginMessage', 'No user found.')); // req.flash is the way to set flashdata using connect-flash
}
// if the user is found but the password is wrong
if (!bcrypt.compareSync(password, rows[0].password))
return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.')); // create the loginMessage and save it to session as flashdata
// all is well, return successful user
return done(null, rows[0]);
});
})
);
};
控制台日志:
您没有在会话中存储授权的 Facebook 用户。您只需在 FacebookStrategy 的实现中调用不带参数的函数 done()
。首先,您应该将 fb 用户存储在您的数据库中,或者 select 如果存在则调用函数完成(接收第一个参数作为错误,第二个作为用户对象)。 here's docs