6

node のパスポートに関する実用的な知識はありますが、次のようなものはありません。

  • 「永続トークン」の生成 ( authlogic/session/session.rb#L35など)
  • パスワードをリセットするための腐りやすいトークンの生成
  • 私を覚えている機能
  • 一部のモデルクラスでのログイン/ログアウトのこれらのプロパティの管理など。

Node.js コミュニティでこれを解決したライブラリはありますか? Devise for Railsと同じくらい堅牢な (または堅牢になる途中の) ものがある場合、それは完璧ですが、このトークンの問題を解決するものはすべて同様に機能します。

クレイジーなことは、多くの例がユーザーidをセッションに保存していることです!

request.session['userId'] = user.get('id')

それはハッキングを求めているだけです。

次のようになります。

require.session['persistenceToken'] = App.User.generateRandomToken()
4

3 に答える 3

8

パスワードリセットのためのワンタイムパスワード(別名シングルユーストークン)戦略は、私が実装するものです。Passportのアーキテクチャを考えると、これは簡単に別のモジュールになる可能性があり、他の誰かがすでにそのようなことを実装していることを知っても驚くことではありません。

私を覚えておいてください。永続性トークンの機能もサポートしたいと思います。できれば、それも別の戦略にしたいと思いますが、コアサポートが必要になる場合があります。req.logInその場合は、 (https://github.com/jaredhanson/passport/blob/master/lib/passport/http/request.js#L28 )の数行でカバーできるはずです。

sidセッションにユーザーIDを保存することに関しては、デフォルトでConnect / Expressにセッションのプロパティが完全にバックエンドに保存され、暗号化されたCookieに設定された一意のものによって検索されることを考えると、大きなリスクはありません。悪意のあるユーザーは、リクエストをスプーフィングするために、一意のsidとセッションシークレットの両方を所有している必要があります。

Mozillaは、アイデンティティの取り組みの一環としてPassportを使用して、BrowserIDをサポートしていない他のプロバイダーにBrowserIDをブリッジしています(browserid-bigtentを参照)。要件を考えると、開発者はPassportが厳格なセキュリティ要件を満たしていることを確認できます。

(最終的には、Passportでのセッションのシリアル化はアプリケーションの責任であるため、セキュリティ上の理由から、必要に応じてユーザーIDの代わりにランダムトークンを使用できます。データをCookieに直接保存する場合は、これを行う必要がありますが、実行することをお勧めします。これは最も不適切なアプローチです。)

モデルでこれらのプロパティを管理する限り、Passportは完全にモデル/ORMに依存しないように設計されています。これらの決定はアプリケーションに任せるのが最善だと思うので、その事実を変更するつもりはありません(そして、この責任を委任した結果、Passportはより柔軟になります)。そうは言っても、この機能を提供するために、他のモジュールがPassportの上に独立して構築する余地があると思います。

そうは言っても、Passportは既存のNode.js認証ソリューションの中で最も堅牢だと思います。最初の3つのリクエストは、それをさらに実現するのに大いに役立ち、簡単に実行できるはずです。これらの機能を取り入れるために協力したいので、遠慮なく私に連絡してください。

最後に、誰かが興味を持っている場合に備えて、現在、authinfoブランチでファーストクラスのAPI認証が行われています。これに基づいて、passport-http-oauthはOAuthサーバー戦略を実装します。これは、OAuthサーバーを組み立てるためのツールキットとしてoauthorizemiddlwareと組み合わせることができます。これはまだ完全には焼き付けられていませんが、準備ができたらPassportのもう1つの効果的な機能になります。

于 2012-06-26T06:42:22.020 に答える
2

その間、次のようなもので十分です。アプリと希望の Cookie 期間に合わせて、必要に応じて調整します。ユーザー名とパスワードのチェックは、ログイン試行を検出するための安っぽい方法ですが、パスポートでは十分に機能します。

app.use(function(req, res, next) {
    if(
            typeof(req.body.username) !== "undefined"
            && typeof(req.body.password) !== "undefined"
            ) {
        if(req.body.remember == 1) {
            req.session.cookie.maxAge = 365*24*60*60*1000;
        }
        else {
            req.session.cookie.maxAge = 24*60*60*1000;
        }
    }
    next();
});
于 2012-11-25T07:30:05.357 に答える
2

これらの機能を Passport.js に組み込みたいと思っていますが、まだ実装されていません。

私は、passport.js serilizeUser() 関数で使用する単純なランダム トークン ジェネレーターを作成し、ニーズに合わせて Justen の回答を少し変更しました。基本的に、唯一の違いは、「記憶」オプションが設定されていない場合、ブラウザが開いている限りセッションが続くことです。

これは、ランダム アクセス トークン ジェネレーターを備えた私のシリアライザーです。私は Mongodb と Mongoose を使用していますが、実装は他のシステムにうまく変換できるはずです。

基本的に、私は時間を取得し、それにランダムな 16 文字の文字列を追加しています。次に、serializeUser() 関数で、他のユーザーが同じトークンを持っていないことを確認します (トークンは一意でなければなりません!)。

User.methods.generateRandomToken = function () {
  var user = this,
      chars = "_!abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890",
      token = new Date().getTime() + '_';
  for ( var x = 0; x < 16; x++ ) {
    var i = Math.floor( Math.random() * 62 );
    token += chars.charAt( i );
  }
  return token;
}; 

シリアライザーは次のとおりです。

passport.serializeUser( function ( user, done ) {

  var createAccessToken = function () {
    var token = user.generateRandomToken();
    app.User.findOne( { accessToken: token }, function (err, existingUser) {
      if (err) return done( err );
      if (existingUser)
        createAccessToken(); // Run the function again - the token has to be unique!
      else {
        user.set( 'accessToken', token );
        user.save( function ( err ) {
          if (err) return done( err );
          return done( null, user.get('accessToken') );
        })
      }
    });
  };

  if ( user._id ) {
    createAccessToken();
  }
});

...そして、これが「remember me」機能を処理する私のバージョンのミドルウェアです。ただし、これをどうにかして serializeUser 関数または Passport.js コアの一部にしたいと考えています。

app.use( express.session( { secret: 'secret_key' } ) );
app.use( function (req, res, next) {
    if ( req.method == 'POST' && req.url == '/login' ) {
      if ( req.body.remember ) {
        req.session.cookie.maxAge = 30*24*60*60*1000; // Rememeber 'me' for 30 days
      } else {
        req.session.cookie.expires = false;
      }
    }
    next();
});
app.use( passport.initialize() );
app.use( passport.session() );

それが何らかの形で役立つことを願っています。それを理解するのに数時間かかりました。これが最善の方法であるかどうかはわかりませんが、今のところうまくいきます.

于 2012-11-27T21:39:58.717 に答える