passport.session()ミドルウェアは何をしますか?


125

Easy Node Authentication:Setup and Local tutorialを使用して、Passport.jsを使用した認証システムを構築しています

私は何をするのか混乱してpassport.session()います。

さまざまなミドルウェアを試してみたところ、express.session()Cookieを介してクライアントにセッションIDを送信するものであることがわかりpassport.session()ましたexpress.session()

アプリケーションの設定方法は次のとおりです。

// Server.jsはアプリケーションを構成し、ウェブサーバーを設定します

//importing our modules
var express = require('express');
var app = express();
var port = process.env.PORT || 8080;
var mongoose = require('mongoose');
var passport = require('passport');
var flash = require('connect-flash');

var configDB = require('./config/database.js');

//Configuration of Databse and App

mongoose.connect(configDB.url); //connect to our database

require('./config/passport')(passport); //pass passport for configuration

app.configure(function() {

    //set up our express application

    app.use(express.logger('dev')); //log every request to the console
    app.use(express.cookieParser()); //read cookies (needed for auth)
    app.use(express.bodyParser()); //get info from html forms

    app.set('view engine', 'ejs'); //set up ejs for templating

    //configuration for passport
    app.use(express.session({ secret: 'olhosvermelhoseasenhaclassica', maxAge:null })); //session secret
    app.use(passport.initialize());
    app.use(passport.session()); //persistent login session
    app.use(flash()); //use connect-flash for flash messages stored in session

});

//Set up routes
require('./app/routes.js')(app, passport);

//launch
app.listen(port);
console.log("Server listening on port" + port);

回答:


139

passport.session() ミドルウェアとして機能してreqオブジェクトを変更し、現在(クライアントCookieからの)セッションIDである「user」値を真の非直列化ユーザーオブジェクトに変更します。

他の答えはいくつかの良い点を作りますが、私はいくつかのより具体的な詳細を提供できると思いました。

app.use(passport.session());

に相当

app.use(passport.authenticate('session'));

ここで、「セッション」は、passportJSにバンドルされている次の戦略を指します。

https://github.com/jaredhanson/passport/blob/master/lib/strategies/session.js

具体的には、59〜60行目:

var property = req._passport.instance._userProperty || 'user';
req[property] = user;

基本的にミドルウェアとして機能し、reqオブジェクトの 'user'プロパティの値を変更して、ユーザーの逆シリアル化されたIDを含める場合。これを正しく機能させるには、カスタムコードにserializeUserdeserializeUser関数を含める必要があります。

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

passport.deserializeUser(function (user, done) {
    //If using Mongoose with MongoDB; if other you will need JS specific to that schema.
    User.findById(user.id, function (err, user) {
        done(err, user);
    });
});

これにより、データベースから正しいユーザーが検索され、クロージャー変数としてコールバックに渡されるdone(err,user);ため、の上記のコードでpassport.session()reqオブジェクトの「ユーザー」値を置き換え、パイル内の次のミドルウェアに渡すことができます。


ねえ、どうすればユーザーの詳細をセッションにのみ保存できますか
初心者

1
「リクエストヘッダー内」?リクエストオブジェクトだけではない
caub 2016年

セッション戦略が認証を復元し、ユーザーをデシリアライズできる場合、私は気づきました。しかし、それでも認証は次の戦略に移行します。これは、私のシナリオではFacebook認証です。セッションがユーザーを回復できる場合でも、次の戦略を呼び出し続ける場合、セッション戦略のポイントは何でしょうか。
nishant 2018

15

ドキュメントから

ConnectまたはExpressベースのアプリケーションでは、Passportを初期化するためにpassport.initialize()ミドルウェアが必要です。アプリケーションで永続的なログインセッションを使用する場合は、passport.session()ミドルウェアも使用する必要があります。

そして

セッション

一般的なWebアプリケーションでは、ユーザーの認証に使用される資格情報は、ログイン要求時にのみ送信されます。認証が成功すると、ユーザーのブラウザに設定されたCookieを介してセッションが確立および維持されます。

後続の各リクエストには認証情報は含まれず、セッションを識別する一意のCookieが含まれます。ログインセッションをサポートするために、Passportはセッションとの間でユーザーインスタンスをシリアル化および逆シリアル化します。

そして

セッションサポートを有効にするかどうかは完全にオプションですが、ほとんどのアプリケーションで推奨されています。有効になっている場合は、passport.session()の前にexpress.session()を使用して、ログインセッションが正しい順序で復元されるようにしてください。


1
迅速な返信ありがとうございますが、私の質問にはお答えできません。また、高速アプリケーションがあり、express.session()を使用する場合、高速サーバーに接続するクライアントで(認証されているかどうかにかかわらず)、Cookieを介してセッションが与えられることに注意してください。それは彼があなたのアプリのログイン保護されたページにいるかどうかに依存しません。私はまだ両方のミドルウェアの違いを知りたいです。
ジョルジュクリンカー2014

1
@GeorgesKrinkerは、serializeUser()およびdeserializeUserメソッドです。エクスプレスミドルウェアはセッション情報を復元しますが、パスポートがユーザー情報を管理する方法とは必ずしも関係ありません。これは、セッションがExpressによって再水和された後に行う必要があります。
ジョシュC.

さて、serializeUser()メソッドとdeserializeUserメソッドがルート内のauthenticate()で実行されるという印象を受けました。
ジョルジュクリンカー2014

@GeorgesKrinker私はそうは思いません。パスポートを使用したとき、ログイン時にのみ.authenticateを呼び出しました。
Josh C.

app.post('/login', passport.authenticate('local'), ...
Josh C.

11

PassportJsログインURLの一部としてユーザーを検証するために使用しますが、このユーザー情報をセッションに格納し、後続のすべての要求で取得する(つまり、ユーザーのシリアル化/非シリアル化)メカニズムが必要です。

したがって、実際には、ログイン認証のようにデータベースやoauthを検索する必要はありませんが、すべてのリクエストでユーザーを認証しています。そのため、パスポートはセッション認証をさらに別の認証戦略として扱います。

そして、この戦略を使用するには、名前が付けられたsession、簡単なショートカットを使用するだけapp.use(passport.session())です。また、この特定の戦略では、明らかな理由により、シリアライズ関数とデシリアライズ関数を実装する必要があることに注意してください。


11

単にセッションを認証するだけです(これはによって生成されますexpress.session())。これは次と同等です。

passport.authenticate('session');

ここのコードで見ることができるように:

https://github.com/jaredhanson/passport/blob/42ff63c/lib/authenticator.js#L233


6
どういう意味ですか?すべてのリクエストで実行され、認証するための資格情報を必ずしも必要としません。各リクエストで発生するワークフローについてもう少し詳しく教えていただけませんか?
ジョルジュクリンカー2014

6
はい、すべてのリクエストで実行されます。Expressによって生成されるセッションIDは、ブラウザーがすべてのリクエストで送信する認証トークンとほぼ同等の一意のIDです。このセッションに格納されたデータは、ユーザーの認証状態を復元するために使用されます。
Jared Hanson

こんにちは@JaredHanson これを見てください。どこにも答えが見つかりませんでしたか?
Saras Arya、2015

@JaredHanson passport.jsを使用して、OAuth2に準拠した広く使用されているオープンソースの認証サーバーで認証しようとしています。しかし、エラーが発生します。問題の解決を手伝ってくれますか?ここにリンクは次のとおりです。 stackoverflow.com/questions/38176236/...
DollarCoffee

@JaredHanson:私が観察しているのは、google-oauthを介してログインした直後にpassport.user情報が追加されたreqオブジェクトが、サイトで新しいページの次のリクエストが行われたときに失われることです。これは予想される動作ですか?次に、最近ログインしたユーザー情報を取得する方法がわかりません。
user1102171
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.