6

初めての公開ノード アプリの基本認証を設定しようとしています。私には 2 つのパスポート戦略があります。1) Facebook 用と 2) Twitter 用です。セキュリティへの影響を理解するまで、少なくとも今のところ、電子メール/パスワード システムを含める予定はありません。すぐに使用できる方法でそれらを機能させ、新しいユーザーを作成するために Mongoose と結び付けることができました。

現在、ソーシャル アカウント ユーザーの重複排除に取り組みたいと考えています。そのため、新しいユーザーが twitter auth を介して入ってくるたびに、電子メールを収集するページにリダイレクトしたいと考えています。セッション変数として返されたトークンとプロファイル オブジェクトを保存し、非表示フィールドとしてフォームを送信するときにそのページでそれらを再利用します。

ただし、Passport を使用してこの側面を実装する方法がわかりません。ここに私がこれまでに持っているコードと、各部分で何をしようとしているのかについてのコメントがあります。基本的に、Twitter ユーザーが古いユーザーであるかどうかを確認しています。そうでない場合は、/addemail ページで再利用するセッション変数を設定し、ユーザー オブジェクトを初期化しています (シリアライズ、デシリアライズ機能が動作するように (よくわかりません)ユーザーが新しいユーザーの場合、セッション変数 NewTwitterUser は true であり、認証/コールバック URL でそれをチェックして、ユーザーを適切なページにリダイレクトしますが、これは機能しません。

//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')
}
4

1 に答える 1

6

最初に、成功したログインを Twitter ルート内の addemail 関数にリダイレクトします。

  app.get('/auth/twitter', passport.authenticate('twitter'));
  app.get('/auth/twitter/callback',
    passport.authenticate('twitter', { successRedirect: '/addemail',
                                       failureRedirect: '/' }));

次に、addemail 関数内で、既にメールがあるかどうかを確認します。その後、適切な場所にリダイレクトできます。

  app.get('/addemail', function(req, res){
      if (req.user.email){
           res.render('email', {title: 'Add your Email'});}
      else {res.redirect('/');}
  });
于 2012-11-13T18:38:29.523 に答える