Próbuję skonfigurować podstawowe uwierzytelnianie dla mojej pierwszej aplikacji węzła publicznego. Mam dwie strategie paszportowe: 1) dla Facebooka i 2) dla Twittera. Na razie nie planuję dodawać systemu e-mail/hasła, dopóki nie zrozumiem konsekwencji dla bezpieczeństwa. Udało mi się sprawić, by pracowali w sposób nieszablonowy i związali się z Mongoose, tworząc nowych użytkowników.Niestandardowe przekierowania w paszporcie
Chcę teraz pracować nad dedupcją użytkowników konta społecznościowego. Tak więc, gdy nowy użytkownik przychodzi za pośrednictwem twittera, chcę przekierować go na stronę zbierającą e-maile. Zapisuję obiekt tokenu i profilu zwrócony jako zmienne sesji i używałbym ich ponownie na tej stronie podczas przesyłania formularza jako ukrytych pól.
Jednak nie mogę zrozumieć, jak zaimplementować ten aspekt za pomocą usługi Passport. Oto kod, który mam do tej pory z komentarzami na temat tego, co próbuję zrobić z każdą częścią. Zasadniczo sprawdzam, czy użytkownik Twittera jest starym użytkownikiem, jeśli nie, ustawiam zmienne sesji, które będę używał ponownie na stronie/addemail, inicjując obiekt użytkownika (tak, że funkcja Serialize, Deserialize ma coś do działania (nie jestem pewien, czy rozumiem) co faktycznie robi Serializing/Deserializing) Teraz, jeśli użytkownik jest nowy, zmienna sesji NewTwitterUser jest prawdziwa i sprawdzam ją w URLu auth/wywołania zwrotnego, aby przekierować użytkownika na odpowiednią stronę.To jednak nie działa
//basic modules and setup
var express = require('express')
, passport = require('passport')
, mongoose = require('mongoose')
, http = require('http')
, util = require('util')
, TwitterStrategy = require('passport-twitter').Strategy
, FacebookStrategy = require('passport-facebook').Strategy
, path = require('path');
var app = express();
//Mongodb setup
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId;
var UserSchema = new Schema({
provider: String,
uid: String,
fb_uid: String,
twitter_uid: String,
name: String,
first_name: String,
gender: String,
fb_username: String,
twitter_username: String,
profile_pic: String,
email: String,
location: String,
birthday: String,
created: {type: Date, default: Date.now}
});
var User = mongoose.model('User', UserSchema);
mongoose.connect('MongoHQ db connection here')'
//User Authentication - Twitter
passport.use(new TwitterStrategy({
consumerKey: 'KEY',
consumerSecret : 'SECRET',
callbackURL: "CALLBACKURL",
passReqToCallback: true
},
function(req, token, tokenSecret, profile, done){
User.findOne({twitter_uid: profile.id}, function(err, user){
if (err) {
console.log('this is an error 1' + err);
return done(err);}
if(user){
console.log('this user' + user);
done(null, user);
} else {
console.log('this is a new user');
req.session.token = token;
req.session.tokenSecret = tokenSecret;
req.session.profile = profile;
req.session.newtwitteruser = true;
var user = new User();
user.uid = profile.id;
done(null, user);
/* This part is commented and is the default code I had if I needed to simply create a Twitter User right here.
var user = new User();
user.provider = profile.provider;
user.uid = profile.id;
user.twitter_uid = profile.id;
user.name = profile.displayName;
user.first_name = profile.displayName[0];
user.twitter_username = profile._json.screen_name;
user.profile_pic = profile._json.profile_image_url;
user.location = profile._json.location;
user.save(function(err){
if(err) {throw err;}
else {done(null, user);}
});*/
}
});
}
));
//User Authentication - Facebook
passport.use(new FacebookStrategy({
clientID: 'ID',
clientSecret: 'SECRET',
callbackURL: "URL"
},
function(accessToken, refreshToken, profile, done){
User.findOne({fb_uid: profile.id}, function(err, user){
if (err) {return done(err);}
if(user){
done(null, user);
} else {
var user = new User();
user.provider = profile.provider;
user.uid = profile.id;
user.fb_uid = profile.id;
user.name = profile.displayName;
user.first_name = profile._json.first_name;
user.gender = profile._json.gender;
user.fb_username = profile._json.username;
user.profile_pic = 'https://graph.facebook.com/' + profile.id + '/picture';
user.email = profile._json.email;
user.location = profile._json.location.name;
user.birthday = profile._json.birthday;
user.save(function(err){
if(err) {throw err;}
else {done(null, user);}
});
}
})
}
));
passport.serializeUser(function(user, done) {
done(null, user.uid);
});
passport.deserializeUser(function(uid, done) {
User.findOne({uid: uid}, function (err, user) {
done(err, user);
});
});
//app configurations
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser("freecookie"));
app.use(express.session({secret:"freecookie"}));
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.errorHandler());
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
});
//Basic Routing
app.get('/', function(req, res){
res.render('home', {title: 'App Title', user: req.user});
});
app.get('/auth/twitter', passport.authenticate('twitter'));
app.get('/auth/twitter/callback',
passport.authenticate('twitter', {failureRedirect: '/login' }),
function(req, res) {
if (req.session.newtwitteruser){
res.redirect('/addemail');}
else {res.redirect('/');}
});
app.get('/addemail', function(req, res){
if (req.session.newtwitteruser){
res.render('email', {title: 'Add your Email'});}
else {res.redirect('/');}
});
app.get('/auth/facebook', passport.authenticate('facebook', {scope: ['email', 'user_location', 'user_birthday'] }));
app.get('/auth/facebook/callback',
passport.authenticate('facebook', { successRedirect: '/', failureRedirect: '/login' }));
app.get('/logout', function(req, res){
req.logout();
res.redirect('/');
});
//create the server
var server = http.createServer(app);
server.listen(app.get('port'));
//Checks if a request is authenticated
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) { return next(); }
res.redirect('/login')
}