6

過去数日間、私は Passport.js を使用して最初のユーザー ログインと認証システムを開発してきました。気まずいことに、私はそれを完成させ、意図したとおりに機能します。問題は、オンラインで多くの記事を読み、数十の例をチェックしたにもかかわらず、コード自体を完全に理解していないように見えることです。その背後にあるプロセスと、なぜそのように起こらなければならないのかを理解するのに何の問題もありません。コードの一部を明確にしていただければ幸いです。これは、私の app.js ファイルに保存されている作業コードです。

// Passport session setup
passport.serializeUser(function (user, done) {
    done(null, user._id);
});

passport.deserializeUser(function (id, done) {
    User.findById(id, function(err, user) {
        done(err, user);
    });
});

// Use the Local Strategy within passport
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: 'Unknown user: ' + username});
        }

        user.comparePassword(password, function(err, isMatch) {
            if (err) {
                return done(err);
            }

            if (isMatch) {
                return done(null, user);
            } else {
                return done(null, false, { message: 'Invalid Password' });
            }
        });
    });
}));

var app = module.exports = express();

app.configure(function () {
    app.set('views', path.join(__dirname + '/views'));
    app.set('view engine', 'html');
    app.engine('html', hbs.__express);
    app.use(express.logger());
    app.use(express.cookieParser());
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(express.session({ secret: 'xxx' }));    
    app.use(passport.initialize());
    app.use(passport.session());
    app.use(app.router);
    app.use(express.static(path.join(__dirname + '/public')));

});

MongoDB (ユーザー - mongoose モデル) を使用しています。また、データベースにパスワードを保存するために、現在 bcrypt を使用しています。

ここで私が理解していない最も重要な部分は、doneコールバック関数だと思います。いくつかの値を渡すだけであることは理解できます。また、最初のパラメーターがエラーで、2 番目のパラメーターがデータであることも理解できます。それでも、パラメーターとして具体的に提供していないため、完全には把握していません。たとえば、次のような関数があるとします。

// Random Function
var randomFunction = function (a, b, done) {
    done(a, b);
};

// Then I would call the randomFunction providing my own **done**
randomFunction('Random', 'Words', function(a, b) { return a + b; });

それでも、私の例では、doneコールバックを指定しているのは私ではありません。それは単に必須のコールバック関数パラメーターですか、それとも次のような通常のミドルウェアの次の関数と同じですか?

function middleware (req, res, next) {
    next(req.user); // pass the req.user to next middleware
}

また、Passport.js は処理するユーザーをどこにバインドしますか? req.userにバインドしますか? また、たとえばユーザー名を表示するために、特定のビューに渡すにはどうすればよいですか?

フィードバックをお待ちしております。

ありがとうございました!

4

1 に答える 1

3

完了コールバック

Local Strategyのコードを見てください:

function Strategy(options, verify) {
  ...
  this._verify = verify;
  ...
}

verifyユーザーを検証するために戦略によって使用される関数であり、ここで指定しました。

passport.use(new LocalStrategy(function (username, password, done) {
    // your verification code here
}));

戦略の後半で、上記のステップから検証機能を呼び出す認証メソッドを見つけることができます。

this._verify(username, password, verified);

usernameこれで、がどこpasswordから来たのかがわかりますdone==verified。コードの後半で、done(err、user、info) 引数を使用してコールバックを呼び出します。簡単に言えば、doneユーザー認証の非同期手順を完了するために必要です。

req.user とビュー

はい、あなたは正しいですreq.user。したがって、次の 2 つの方法でビューに渡すことができます。

  1. 関数の引数としてres.renderドキュメントを見る

    res.render('some-template', { name: req.user });
    
  2. res.localsある種のコンテキスト プロバイダーとして使用します (ユーザー オブジェクトは、 で定義されているすべてのビューで使用できるようになりますapp.router)。ドキュメントを見る

    // before app.use(app.router);
    app.use(function(req, res, next) {
       res.locals.user = req.user;
       next();
    });
    
于 2013-10-24T13:07:11.487 に答える