2

私は自分のサイトでいくつかのパスポート認証戦略を使用していますが、これはうまく機能しますが、セッションIDによってユーザーを自動的に承認するDemoまたは(呼び出すことができるsession)戦略が必要です。ユーザーがナビゲートするときに手動で実行していますページに対して/demo、セッションIDを使用してdb(mongodb)でクエリを実行し、ユーザーが存在する場合はそのユーザーでページをレンダリングし、存在しない場合は作成します。

app.get('/demo', function(req,res) {
  db.User.findOne({ 'accounts.kind': 'demo', 'accounts.sid': req.sessionID }, function(err, user) {
    if (user) {
      res.render( 'home', {
        user: user
      });
    } else {
      var user = new db.User();
      user.accounts.push({
        kind: 'demo',
        sid: req.sessionID,
        created: Date.now
      });
      req.session.userId = user._id;

      user.save(function(err) {
        if(err) { throw err; }
        res.render( 'home', {
          user: user
        });
      });
    }
  });
});

ユーザースキーマは次のようになります。

UserSchema = new Schema({
  uname: {type: String},
  accounts: [],
  docs:[{type:Schema.Types.ObjectId, ref:'Doc'}]
})

動作しますが、セッション変数を設定する必要があります。このメソッドはユーザーにログインしないためreq.user、リクエストにはログインしませんが、そのセッション変数を使用すると、ユーザーがデモユーザーであるかどうかを確認できます。

if (req.user) {
    userid = req.user._id.toString();
  } else {
    userid = req.session.userId;
  }

既存のパスポート戦略の1つを使用して、これを行うためのよりエレガントな方法があると確信しています。パスポート-httpパスポート-匿名、その他いくつかあることがわかりますが、どちらを使用すればよいかわかりません。

ユーザーのデータベースエントリを作成することは私にとって重要です。後で別のアカウントを添付することができます。

4

3 に答える 3

6

結局のところ、この場合、カスタム戦略を作成する必要はありません。公式のLocalStrategyには(文書化されていない)オプションがあり、検証関数でオブジェクトにpassReqToCallbackアクセスできることがわかりました。req検証機能を変更するだけで、LocalStrategyを使用してあらゆる種類の処理を実行できます。

passport.use(new LocalStrategy({
    passReqToCallback: true
}, function(req, username, password, done) {
    //now that you have req object, you can
    //probably do whatever you need to do right here
});

この関数は、デフォルトの3ではなく、objectでreq, username, password, done始まる4つの引数を取るようになったことに注意してください。req

これで時間を節約できることを願っています。LocalStrategyコードを実行する前に、これを回避するために1時間ほど費やしました。

于 2013-02-15T19:43:02.417 に答える
3

私はそれを次のように解決することができます:新しい戦略を定義し、

var passport = require('passport')
  , util = require('util');

function DemoStrategy(options, verify) {
  if (typeof options == 'function') {
    verify = options;
    options = {};
  }
  if (!verify) throw new Error('Demo Basic authentication strategy requires a verify function');

  passport.Strategy.call(this);
  this.name = 'demo';
  this._verify = verify;
}

util.inherits(DemoStrategy, passport.Strategy);

DemoStrategy.prototype.authenticate = function(req) {
  var self = this;
  this._verify( req, function(err, user) {
    if (err) { return self.error(err); }
    self.success(user);
  });
}

module.exports.Strategy = DemoStrategy;

ルート:

app.get('/auth/demo', 
    passport.authenticate('demo'),
    function(req,res) { 
      res.redirect('/');
     }
  );

およびpassport.use部分:

passport.use(new DemoStrategy( 
  function(req, done) {
    console.log( 'using demo strategy, req: ', req );
    if (req.user) {
      // place code here, if we want to attach to an existing account
    } else {
      db.User.findOne({ 'accounts.kind': 'demo', 'accounts.sid': req.sessionID }, function(err, dbuser) {
        if (dbuser) {
          done(null,dbuser);
        } else {
          var user = new db.User();
          user.accounts.push({
            kind: 'demo',
            sid: req.sessionID,
            created: Date.now
          });

          user.save(function(err) {
            if(err) { throw err; }
            done(null,user);
          });
        }
      });
    }
  }
));

多分それはバグでいっぱいで、エラー処理は完全ではありませんが、正しい解決策のようです、それは非常に高く評価されているパスポートライブラリに統合されています、

于 2012-10-17T15:46:58.447 に答える
2

パスポート構成からセクション4を確認してください。これは、セッションIDをCookieに入れ、ユーザーが戻ってきたときにデータを取得するためのコードです。戦略は必要ありません。

passport.serializeUser(function(user, done) {
  done(null, user.id);
});

passport.deserializeUser(function(id, done) {
  User.findById(id, function (err, user) {
    done(err, user);
  });
});
于 2012-10-17T00:04:29.980 に答える