パスポート[認証の構成]のドキュメントには、不思議な機能「完了」を使用したかなり怖い機能があります。
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);
});
}
));
さて、 エクスプレスドキュメント には、nextと呼ばれるものを渡すメソッドがかなりあります。
app.use(function(err, req, res, next){
console.error(err.stack);
res.status(500).send('Something broke!');
});
これは、エクスプレスとパスポートの2つのフレームワークの違いですか?それとも彼らは2つの別々のことをしていますか?
いいえ、使用目的が異なります。 Expressはnode.jsのアプリケーションフレームワークとして使用されますが、passportはWebアプリケーションの認証部分を処理するだけです。
next()はconnectの一部であり、これは明示的な依存関係です。 next()を呼び出す目的は、Expressスタックの次のミドルウェアをトリガーすることです。
next()
の概念をより簡単に理解するために、 express here 上に構築されたサンプルアプリを見ることができます。
指摘された行でわかるように、アプリケーションはルートレベルのミドルウェアを使用して、ユーザーがログインしているかどうかを確認します。
_app.get('/account', ensureAuthenticated, function(req, res){
_
ここでensureAuthenticatedは、次のように下部で定義されているミドルウェアです。
_function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) { return next(); }
res.redirect('/login')
}
_
ユーザーが認証されているかどうかを確認できるように、関数はnext()
を呼び出し、上記のルートハンドラーの次のレイヤーに制御を渡します。そうでない場合は、next()
を呼び出さなくても別のルートにリダイレクトします。
一方、done()は、パスポート認証用に作成する戻りURLハンドラーをトリガーするために使用されます。完了した動作の詳細を理解するには、 ここのパスポート のコードサンプルを見て、カスタムコールバックというタイトルのセクションを確認してください。
_app.get('/login', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) { return next(err); }
if (!user) { return res.redirect('/login'); }
req.logIn(user, function(err) {
if (err) { return next(err); }
return res.redirect('/users/' + user.username);
});
})(req, res, next);
});
_
ここで、_passport.authenticate
_の2番目のパラメーターは、パスポート戦略から呼び出すdone()
の定義です。
ここで、上記の2つのリンクのサンプルコードを確認することで、ドキュメントよりもその動作を理解するのに大いに役立ちました。同じことをすることをお勧めします。
passportのdone()は、最初のパラメーターにエラー(またはnull)を渡し、2番目のパラメーターとしてユーザーオブジェクトを渡すように求めています。
expressのnext()は、最初のパラメーターにエラーがあるか、エラーがなかった場合はパラメーターなしで呼び出されることを望んでいます。最初のパラメータでコントロールをリダイレクトするルートの名前を渡すこともできますが、これはあまり一般的ではありません
混乱するかもしれないので、バックアップしましょう。
ExpressはWebアプリケーションフレームワークです。非常に広い意味で、ユーザーをリソースに誘導する責任があります。
パスポートは認証フレームワークです。ユーザーが上記のリソースにアクセスできるようにする責任があります。
どちらのフレームワークにも、ミドルウェアのアイデアがあります。ミドルウェアは基本的に一般化された制御フローです。たとえば、一部のExpressフレームワークでは、次のように言うことができます。
ルートをリクエストするときは、パラメータxが有効であることを確認してください/user/:x
ユーザーがセッションなどを持っていることを確認してください
そして、すべてのミドルウェアが実行されたら、アプリケーションを実行します
例えば、
router.get('/', function(req, res) { // when the '/' route is requested
res.render('index', { title: 'Express' }); // send index.html
});
Passportでは、ミドルウェアの概念も使用していますが、next()の代わりにdone()を使用しているため、少し複雑です。詳細については、このページを参照してください
http://toon.io/understanding-passportjs-authentication-flow/