1

私は3種類のユーザーを持っています:

  1. ビューアー(サインインへのリンク: auth/ v /twitter)
  2. 作成者(サインインへのリンク: auth/ c /twitter)
  3. 管理者(サインインへのリンク: auth/ a /twitter)

また、3つの異なるデータベース/コレクションがあります

  1. c_viewer
  2. c_creator
  3. c_admin

ユーザーの種類ごとに、サインインするためのリンクが異なります。

それでは、コードを見てみましょう

var passport = require('passport')
   ,TwitterStrategy = require('passport-twitter').Strategy;

passport.use(new TwitterStrategy({
  consumerKey: config.development.tw.consumerKey,
  consumerSecret: config.development.tw.consumerSecret,
  callbackURL: config.development.tw.callbackURL
},

function(token, tokenSecret, profile, done) {
  process.nextTick(function(req, res) {
    var query = User.findOne({ 'twId': profile.id});
    query.exec(function(err, oldUser){
      if(oldUser) {
        done(null, oldUser);
      } else {
        var newUser = new User();
        newUser.twId = profile.id;
        newUser.twUsername = profile.username;
        newUser.name = profile.displayName;
        newUser.avatar = profile.photos[0].value;
     -> newUser.age = req.body.creator.age; ???
        newUser.save(function(err) {
          if(err) throw err;
          done(null, newUser);
        });
      };
    });
  });
}));

app.get('/auth/c/twitter', passport.authenticate('twitter'),
function(req, res) {
  var userUrl = req.url;
  // codes to pass the userUrl to TwitterStrategy
});
app.get('/auth/twitter/callback', 
passportForCreator.authenticate('twitter', { successRedirect: '/dashboard', failureRedirect: '/' }));

そして、これが私のフォームです

<input type="text" name="creator[age]" placeholder="How old are you?">
<a id="si" class="btn" href="/auth/c/twitter">Sign in</a>

私の質問:

1.<input>ログインプロセスにデータを渡すことはできますか? TwitterStrategy で入力データを読み取り、db に保存できます
2.ログイン URL (auth/ c /twitter) から "c" を取得して TwitterStrategy に渡すことはできますか? そのため、別のデータベース/コレクションをチェックインして、クエリを変更するだけです。

4

1 に答える 1

3

アイデアは、認証のためにTwitterでユーザーをリダイレクトする前に値を保存し、ユーザーが戻ってきたらこれらの値を再利用することです。

OAuth2 にはスコープ パラメーターが含まれており、そのケースに完全に適合します。残念ながら、TwitterStrategy は OAuth1 に基づいています。しかし、私たちはそれに取り組むことができます!

次のトリックは、ユーザーを作成するときです。戦略を宣言するときは (入力データにアクセスできないため) 行うべきではありませんが、少し後で、最後の認証コールバック でコールバック引数を参照してください

戦略を宣言する:

passport.use(new TwitterStrategy({
  consumerKey: config.development.tw.consumerKey,
  consumerSecret: config.development.tw.consumerSecret,
  callbackURL: config.development.tw.callbackURL
}, function(token, tokenSecret, profile, done) {
  // send profile for further db access
  done(null, profile);
}));

認証 URL を宣言する場合 (a/twitter と v/twitter について繰り返します):

// declare states where it's accessible inside the clusre functions
var states={};

app.get("/auth/c/twitter", function (req, res, next) {
  // save here your values: database and input
  var reqId = "req"+_.uniqueId();
  states[reqId] = {
    database: 'c',
    age: $('input[name="creator[age]"]').val()
  };
  // creates an unic id for this authentication and stores it.
  req.session.state = reqId;
  // in Oauth2, its more like : args.scope = reqId, and args as authenticate() second params
  passport.authenticate('twitter')(req, res, next)
}, function() {});

次に、コールバックを宣言するとき:

app.get("/auth/twitter/callback", function (req, res, next) {
  var reqId = req.session.state;
  // reuse your previously saved state
  var state = states[reqId]

  passport.authenticate('twitter', function(err, token) {
    var end = function(err) {
      // remove session created during authentication
      req.session.destroy()
      // authentication failed: you should redirect to the proper error page
      if (err) {
        return res.redirect("/");
      }
      // and eventually redirect to success url
      res.redirect("/dashboard");
    }

    if (err) {
      return end(err);
    }

    // now you can write into database:
    var query = User.findOne({ 'twId': profile.id});
    query.exec(function(err, oldUser){
      if(oldUser) {
        return end()
      } 
      // here, choose the right database depending on state
      var newUser = new User();
      newUser.twId = profile.id;
      newUser.twUsername = profile.username;
      newUser.name = profile.displayName;
      newUser.avatar = profile.photos[0].value;
      // reuse the state variable
      newUser.age = state.age
      newUser.save(end);
    });
  })(req, res, next)
});
于 2013-08-22T08:24:50.073 に答える