node-jwt-simpleを使用したpassport-local


87

認証が成功したときに、passport-localを組み合わせてJWTトークンを返すにはどうすればよいですか?

node-jwt-simpleを使用してpassport.jsを確認したいのですが、どうすればよいかわかりません。

var passport = require('passport')
  , LocalStrategy = require('passport-local').Strategy;

passport.use(new LocalStrategy(
  function(username, password, done) {
    User.findOne({ username: username }, function(err, user) {
      if (err) { return done(err); }
      if (!user) {
        return done(null, false, { message: 'Incorrect username.' });
      }
      if (!user.validPassword(password)) {
        return done(null, false, { message: 'Incorrect password.' });
      }
      return done(null, user);
    });
  }
));

done()を呼び出すときにトークンを返すことは可能ですか?このようなもの...(ちょうど擬似コード)

if(User.validCredentials(username, password)) {
  var token = jwt.encode({username: username}, tokenSecret);
  done(null, {token : token}); //is this possible?
}

そうでない場合、トークンを返すにはどうすればよいですか?

回答:


123

私はそれを考え出した!

まず、正しい戦略を実装する必要があります。私の場合はLocalStrategy、そして検証ロジックを提供する必要があります。例えば日本酒をパスポートローカルで使ってみましょう。

var passport = require('passport')
  , LocalStrategy = require('passport-local').Strategy;

passport.use(new LocalStrategy(
  function(username, password, done) {
    User.findOne({ username: username }, function(err, user) {
      if (err) { return done(err); }
      if (!user) {
        return done(null, false, { message: 'Incorrect username.' });
      }
      if (!user.validPassword(password)) {
        return done(null, false, { message: 'Incorrect password.' });
      }
      return done(null, user);
    });
  }
));

あなたが提供する検証コールバックはfunction(username, password, done)、ユーザーを見つけ、パスワードが一致するかどうかを確認します(質問と私の回答の範囲を超えています)

passport.jsは、いくつかの要素が機能することを期待しています。1つは、戦略でユーザーを返すことです。私はコードのその部分を変更しようとしていましたが、それは間違っていました。コールバックはfalse、検証が失敗した場合、およびobject(検証されたユーザー)が成功した場合を想定しています。

では、JWTを統合する方法は?

ログインルートでは、成功した認証または失敗した認証を処理する必要があります。そして、ここにJWTトークン作成を追加する必要があります。そのようです:

(セッションを無効にすることを忘れないでください。そうしないと、シリアライズおよびデシリアライズ機能を実装する必要があります。また、セッションを永続化しない場合は必要ありません。トークンベースの認証を使用している場合は不要です)

パスポートローカルの例から:(JWTトークンが追加されています)

// POST /login
//   This is an alternative implementation that uses a custom callback to
//   achieve the same functionality.
app.post('/login', function(req, res, next) {
  passport.authenticate('local', function(err, user, info) {
    if (err) { return next(err) }
    if (!user) {
      return res.json(401, { error: 'message' });
    }

    //user has authenticated correctly thus we create a JWT token 
    var token = jwt.encode({ username: 'somedata'}, tokenSecret);
    res.json({ token : token });

  })(req, res, next);
});

これで完了です。/ loginとPOSTユーザー名とパスワード(常にSSLを使用する必要があります)を呼び出すと、上記の最初のコードスニペットは、指定したユーザー名に基づいてユーザーを検索し、パスワードが一致することを確認します(もちろん、ニーズに合わせて変更してください)。

その後、ログインルートが呼び出され、そこでエラーまたは有効なトークンを返すことができます。

これが誰かを助けることを願っています。そして私が何か間違いをしたり何かを忘れたりした場合は私に知らせてください。


3
PassportのBasicStrategyまたはDigestStrategyは、他の2つのオプションです。ただし、どちらのセッションも機能する必要がないため、基本戦略とローカル戦略の間に大きな違いはないようです。ローカルがリダイレクトURLを要求するだけです(APIの使いやすさが少し低下します)。
funseiki

1
ちょっと@cgiacomiトークンをチェックするルートの例を挙げられますか?
Matt Kim

3
@ matt-kimさん、実際にはトークンを保存しません。一時的なものです。それが最善の方法かどうかはわかりませんが、これは私が行うことです。ユーザーを認証し、トークンを生成してクライアントに返します。トークンは、クライアントがWebサイトである場合はlocalStorageに保存されますが、iPhone / Androidアプリに保存することもできます。クライアントがリソースをリクエストする必要がある場合、クライアントは保存されたトークンをバックエンドに送信します。Passportがトークンを処理します。 これは、トークンgist.github.com/cgiacomi/cd1efa187b8cccbe2a61を処理するベアラー戦略の要点 です。:)
cgiacomi

1
@cgiacomiさん、こんにちは。多分それは明らかですが、カスタムコールバックを使用するときにセッションを無効にする方法を説明できますか?
MrMuh 2014

2
@MrMuhチェックアウトリンクgist.github.com/cgiacomi/cd1efa187b8cccbe2a61私のコメントでセッションを無効にする方法を示します:passport.authenticate( 'bearer'、{session:false})
cgiacomi

18

これは素晴らしい解決策です、これを追加したいだけです:

var expressJwt = require('express-jwt');

app.use('/api', expressJwt({secret: secret}));

私が使用したい「 - JWTを表現する」トークンを検証します。

ところで、この記事は、Angularを使用してクライアント側でトークンを処理し、すべてのリクエストでトークンを送り返す方法を学ぶのに最適です

https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/


2
express-jwtは認証にしか使用していませんがpassport-jwt、などの他のパッケージのドキュメントを読んでいるので、に固執すると思いますexpress-jwt。ずっとシンプルでずっと良いIMO
bobbyz 2016年

ただFYI express-jwtは更新トークンのサポートを提供しません。
user3344977

3

ここに私が具体的にAPIトークンのみを使用するために取り組んでいるボイラープレートがあります(セッションはありません...もちろんそのセッションは悪いものではありません。トークンアプローチを使用しているだけです):https : //github.com/roblevintennis/passport -api-tokens

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.