我可以为护照制定多种 Facebook 策略吗?
Can I have multiple facebook strategies for passport?
我想以不同的方式处理以下 passport-facebook 相关操作。
- 使用 Facebook 注册
- 使用 Facebook 登录
- 将现有帐户连接到 Facebook
'sign-up'我想do/check:
- 如果用户已经存在(基于 facebook oauth id),重定向到登录。
- 如果用户已经存在(基于 facebook 个人资料中的电子邮件地址),提示用户使用电子邮件登录,然后连接他们的 facebook 帐户。
- 创建新用户并登录。
对于'log-in'和'connect account'我想执行一系列其他checks/operations。
我查看了 passport documentation for facebook and the passport-facebook module 和一堆相关的 Stack Overflow 问题,但我仍在为如何实现它而苦苦挣扎。
如何使用不同的回调 URL 和选项实施不同的 facebook 策略(通过 passport)?
经过大量挖掘,这就是我最终做的事情:
创建 3 个单独的护照策略。
每个都有不同的名称(facebookSignUp vs facebookLogIn vs facebookConnect)和不同的 callbackURL 路径(.../sign-up/clbk vs .../log-in/clbk vs .../connect/clbk)。
// facebook strategy 1 (sign-up with facebook)
passport.use('facebookSignUp', new FacebookStrategy({
clientID: FACEBOOOK_APP_ID,
clientSecret: FACEBOOK_APP_SECRET,
callbackURL: 'http://website/auth/facebook/sign-up/clbk'
},
function(accessToken, refreshToken, profile, clbk) {
return clbk(profile);
}
));
// facebook strategy 2 (log-in with facebook)
...
// facebook strategy 3 (connect facebook to existing account)
...
为每个策略创建路线。
Facebook认证后的初始请求路由和回调路由。所以每个策略有 2 条路线。
var member = require('../member'); // member module controller
// sign-up with facebook
app.route('/auth/facebook/sign-up')
.get(member.facebookSignUp); // passport redirect to facebook for authentication
// sign-up with facebook callback
app.route('/auth/facebook/sign-up/clbk')
.get(
member.facebookSignUpClbk, // parse facebook profile to create new user & check for existing account -> redirect to log-in route
member.checkEmail, // check if email is already used -> throw error 'please log in with email, then connect facebook in settings'
member.checkUrl, // get unique url
member.signUp, // create new user & sign-in
member.email.welcome, // send welcome email
member.facebookRedirectDashboard // redirect to member dashboard
);
// log-in with facebook
app.route('/auth/facebook/log-in')
.get(member.facebookLogIn); // passport redirect to facebook for authentication
// log-in with facebook callback
app.route('/auth/facebook/log-in/clbk')
.get(
member.facebookLogInClbk, // authenticate user and log-in & check if user exists (fb oauth id or email address) -> throw error 'please sign up with facebook or log in with email'
member.lastLogin, // update user's last login field
member.facebookRedirectDashboard // redirect to dashboard
);
// connect facebook profile to existing account
...
// connect facebook profile to existing account clbk
...
下面files/functions.
进行实际护照认证的地方
member.facebookSignUp 只调用 passport.authenticate(),重定向到 facebook。
// member.facebookSignUp
exports.facebookSignUp = function(req, res, next) {
passport.authenticate('facebookSignUp', { // use the 'facebookSignUp' strategy
display: null, // null = let facebook decide (or 'page' (default), 'popup', 'touch', etc)
scope: [
'public_profile', // profile returned by default, but specified here anywhere
'email', // ask for email address
'user_location' // ask for location
]
})(req, res);
};
member.facebookSignUpClbk 在facebook 授权用户并重定向到回调路由后执行。这是其他一切发生的地方。
// member.facebookSignUpClbk
exports.facebookSignUpClbk = function(req, res, next) {
// parse profile & plug into req.body for new user creation in later fxn
function parseProfile(profile) {
// user doc
req.body = {};
// facebook profile data
req.body.facebook = (profile._json) ? profile._json : {id: profile.id};
// name
...
// email
...
next();
}
// check existing users (mongoose/mongodb)
function checkUser(profile) {
User.findOne({query}, function(err, userDoc) {
if (err) {
return res.redirect(
'http://'+req.headers.host+
'?header=Sign-Up Error!'+
'&message=We had trouble signing you up with Facebook. Please try again'
);
} else if (userDoc) {
// redirect to log-in fxn
return res.redirect('http://website/auth/facebook/log-in');
} else {
parseProfile(profile);
}
});
}
// passport authentication
function passportAuth() {
passport.authenticate('facebookSignUp', function(profile) {
if (!profile || !profile.id) {
return res.redirect(
'http://'+req.headers.host+
'?header=Sign-Up Error!'+
'&message=We had trouble signing you up with Facebook. Please try again or sign-up via email.'
);
} else {
checkUser(profile);
}
})(req, res);
}
// start process
passportAuth();
};
member.facebookLogIn、.facebookLogInClbk、.facebookConnect 和 .facebookConnectClbk 的设置方式类似,只是 'Clbk' 函数中的逻辑不同,具体取决于我要执行的操作。
希望对您有所帮助!
我想以不同的方式处理以下 passport-facebook 相关操作。
- 使用 Facebook 注册
- 使用 Facebook 登录
- 将现有帐户连接到 Facebook
'sign-up'我想do/check:
- 如果用户已经存在(基于 facebook oauth id),重定向到登录。
- 如果用户已经存在(基于 facebook 个人资料中的电子邮件地址),提示用户使用电子邮件登录,然后连接他们的 facebook 帐户。
- 创建新用户并登录。
对于'log-in'和'connect account'我想执行一系列其他checks/operations。
我查看了 passport documentation for facebook and the passport-facebook module 和一堆相关的 Stack Overflow 问题,但我仍在为如何实现它而苦苦挣扎。
如何使用不同的回调 URL 和选项实施不同的 facebook 策略(通过 passport)?
经过大量挖掘,这就是我最终做的事情:
创建 3 个单独的护照策略。
每个都有不同的名称(facebookSignUp vs facebookLogIn vs facebookConnect)和不同的 callbackURL 路径(.../sign-up/clbk vs .../log-in/clbk vs .../connect/clbk)。
// facebook strategy 1 (sign-up with facebook)
passport.use('facebookSignUp', new FacebookStrategy({
clientID: FACEBOOOK_APP_ID,
clientSecret: FACEBOOK_APP_SECRET,
callbackURL: 'http://website/auth/facebook/sign-up/clbk'
},
function(accessToken, refreshToken, profile, clbk) {
return clbk(profile);
}
));
// facebook strategy 2 (log-in with facebook)
...
// facebook strategy 3 (connect facebook to existing account)
...
为每个策略创建路线。
Facebook认证后的初始请求路由和回调路由。所以每个策略有 2 条路线。
var member = require('../member'); // member module controller
// sign-up with facebook
app.route('/auth/facebook/sign-up')
.get(member.facebookSignUp); // passport redirect to facebook for authentication
// sign-up with facebook callback
app.route('/auth/facebook/sign-up/clbk')
.get(
member.facebookSignUpClbk, // parse facebook profile to create new user & check for existing account -> redirect to log-in route
member.checkEmail, // check if email is already used -> throw error 'please log in with email, then connect facebook in settings'
member.checkUrl, // get unique url
member.signUp, // create new user & sign-in
member.email.welcome, // send welcome email
member.facebookRedirectDashboard // redirect to member dashboard
);
// log-in with facebook
app.route('/auth/facebook/log-in')
.get(member.facebookLogIn); // passport redirect to facebook for authentication
// log-in with facebook callback
app.route('/auth/facebook/log-in/clbk')
.get(
member.facebookLogInClbk, // authenticate user and log-in & check if user exists (fb oauth id or email address) -> throw error 'please sign up with facebook or log in with email'
member.lastLogin, // update user's last login field
member.facebookRedirectDashboard // redirect to dashboard
);
// connect facebook profile to existing account
...
// connect facebook profile to existing account clbk
...
下面files/functions.
进行实际护照认证的地方member.facebookSignUp 只调用 passport.authenticate(),重定向到 facebook。
// member.facebookSignUp
exports.facebookSignUp = function(req, res, next) {
passport.authenticate('facebookSignUp', { // use the 'facebookSignUp' strategy
display: null, // null = let facebook decide (or 'page' (default), 'popup', 'touch', etc)
scope: [
'public_profile', // profile returned by default, but specified here anywhere
'email', // ask for email address
'user_location' // ask for location
]
})(req, res);
};
member.facebookSignUpClbk 在facebook 授权用户并重定向到回调路由后执行。这是其他一切发生的地方。
// member.facebookSignUpClbk
exports.facebookSignUpClbk = function(req, res, next) {
// parse profile & plug into req.body for new user creation in later fxn
function parseProfile(profile) {
// user doc
req.body = {};
// facebook profile data
req.body.facebook = (profile._json) ? profile._json : {id: profile.id};
// name
...
// email
...
next();
}
// check existing users (mongoose/mongodb)
function checkUser(profile) {
User.findOne({query}, function(err, userDoc) {
if (err) {
return res.redirect(
'http://'+req.headers.host+
'?header=Sign-Up Error!'+
'&message=We had trouble signing you up with Facebook. Please try again'
);
} else if (userDoc) {
// redirect to log-in fxn
return res.redirect('http://website/auth/facebook/log-in');
} else {
parseProfile(profile);
}
});
}
// passport authentication
function passportAuth() {
passport.authenticate('facebookSignUp', function(profile) {
if (!profile || !profile.id) {
return res.redirect(
'http://'+req.headers.host+
'?header=Sign-Up Error!'+
'&message=We had trouble signing you up with Facebook. Please try again or sign-up via email.'
);
} else {
checkUser(profile);
}
})(req, res);
}
// start process
passportAuth();
};
member.facebookLogIn、.facebookLogInClbk、.facebookConnect 和 .facebookConnectClbk 的设置方式类似,只是 'Clbk' 函数中的逻辑不同,具体取决于我要执行的操作。
希望对您有所帮助!