私は郵便配達員で完全にテストされたCRUD機能を備えたMEANアプリケーションを持っています。幸運なことに今しばらくログインを維持しようとしています。私は以下を読んで試しました
しかし、セッションでのログインを保持するのではなく、ユーザーを登録してログインすることしかできませんでした。
ここ は完全なgithubリポジトリへのリンクです(最新の変更を確認する場合は、developブランチを確認してください)
以下は、プロジェクトのコード例と、ポストマンの結果のスクリーンショット、およびコンソールログを使用したユーザーログインの理解です。
私は次のauth.jsファイルを持っています、それはパスポートを設定します
_var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
module.exports = function(app, user){
app.use(passport.initialize());
app.use(passport.session());
// passport config
passport.use(new LocalStrategy(user.authenticate()));
passport.serializeUser(function(user, done) {
console.log('serializing user: ');
console.log(user);
done(null, user._id);
});
passport.deserializeUser(function(id, done) {
user.findById(id, function(err, user) {
console.log('no im not serial');
done(err, user);
});
});
};
_
これは、次のようなサーバーファイルで呼び出されます
_//code before
var user = require('./models/user.js');
var auth = require('./modules/auth.js')(app, user);
// code after
_
私のルートには、次のようなログインルートがあります
_router.post('/login', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) {
return next(err);
}
if (!user) {
return res.status(401).json({
err: info
});
}
req.logIn(user, function(err) {
if (err) {
return res.status(500).json({
err: 'Could not log in user'
});
}
res.status(200).json({
status: 'Login successful!'
});
});
})(req, res, next);
});
_
このルートworksはpostmanでテストされています。 「joe」と「pass」の詳細を入力すると、次の応答が返されます。
このルートがヒットすると、ユーザーがシリアル化されていることもコンソールで確認できます。
これは私が迷子になる場所です。少し質問があります。
req.session.passport.user
_をクライアントに返すべきですか?セッションをテストするための2番目のルート設定があります。次のとおりです。
_router.get('/checkauth', passport.authenticate('local'), function(req, res){
res.status(200).json({
status: 'Login successful!'
});
});
_
ルートにアクセスする前にユーザーセッションが存在するかどうかをテストするためにpassport.authenticate('local')
の部分がありますが、これを実行してもログイン後でも200の応答が返されません。
このルートは、_req.session.passport.user
_がヘッドで渡されるか、または認証を必要とするhttp要求のデータ引数として渡されることを期待していますか?
私が何かを見逃したか、何か間違ったことを理解している場合は教えてください、入力は大歓迎です。皆さんありがとう。
ユーザーは現在サーバー上のセッションにいますか?
いいえ、セッションを実際にメモリ/データベースに保存するには、app.use(passport.session());
の前に_express-session
_ミドルウェアを使用する必要があります。このミドルウェアは、ブラウザーにCookieを設定し、ブラウザーから送信されたCookieを_req.session
_オブジェクトに変換します。 PassportJSは、そのオブジェクトを使用して、ユーザーをさらに逆シリアル化します。
req.session.passport.userをクライアントに返送しますか?
クライアントがログイン時にuser
リソースを期待している場合は、そうする必要があります。それ以外の場合、ユーザーオブジェクトをクライアントに送信する理由はありません。
今後のすべてのリクエストでセッションIDが必要ですか?
はい、今後のすべてのリクエストには、セッションIDが必要です。ただし、クライアントがブラウザの場合、何も送信する必要はありません。ブラウザはセッションIDをCookieとして保存し、Cookieの有効期限が切れるまで、以降のすべてのリクエストに対してセッションIDを送信します。 _express-session
_はそのCookieを読み取り、対応するセッションオブジェクトを_req.session
_としてアタッチします。
セッションのテスト
passport.authenticate('local')
は、POST body。からのユーザー資格情報を認証するためのものです。ログインルートにのみ使用する必要があります。
ただし、ユーザーが他のすべてのルートで認証されているかどうかを確認するには、_req.user
_が定義されているかどうかを確認できます。
_function isAuthenticated = function(req,res,next){
if(req.user)
return next();
else
return res.status(401).json({
error: 'User not authenticated'
})
}
router.get('/checkauth', isAuthenticated, function(req, res){
res.status(200).json({
status: 'Login successful!'
});
});
_
@hassansinが言うように、セッション管理を実装するミドルウェアを使用する必要があります。 passport.session()ミドルウェアは、パスポートフレームワークをセッション管理に接続し、セッション自体を実装しません。 express-session
ミドルウェア セッション管理を実装します。次の方法でauth.jsを変更する必要があります
var passport = require('passport');
var session = require('express-session');
var LocalStrategy = require('passport-local').Strategy;
module.exports = function(app, user){
app.use(session({secret: 'some secret value, changeme'}));
app.use(passport.initialize());
app.use(passport.session());
// passport config
passport.use(new LocalStrategy(user.authenticate()));
passport.serializeUser(function(user, done) {
console.log('serializing user: ');
console.log(user);
done(null, user._id);
});
passport.deserializeUser(function(id, done) {
user.findById(id, function(err, user) {
console.log('no im not serial');
done(err, user);
});
});
};
この場合、セッションエンジンはメモリ内ストアを使用しており、アプリケーションをスケーリングして負荷分散を適用すると機能しなかったことに注意してください。この開発状態に到達すると、 connect-redis
セッションストア が必要になります。
また、セッションミドルウェアコールで使用されるシークレット値を変更し、すべてのアプリケーションインスタンスで同じ値を使用する必要があることに注意してください。
パスポートのドキュメント 、req.user
は認証されたユーザーに設定されます。ただし、これを機能させるには、express-session
モジュール。パスポートが機能するためにすでに持っているもの以外に何も必要ないはずです。
セッションをテストする限り、req.userが設定されているかどうかを確認するミドルウェア機能を使用できます。設定されている場合はユーザーが認証されていることがわかり、設定されていない場合はユーザーをリダイレクトできます。
たとえば、認証する任意のルートで使用できるミドルウェア機能を使用できます。
authenticated.js
module.exports = function (req, res, next) {
// if user is authenticated in the session, carry on
if (req.user) {
next();
}
// if they aren't redirect them to the login page
else {
res.redirect('/login');
}
};
コントローラー
var authenticated = require('./authenticated');
router.get('/protectedpage', authenticated, function(req, res, next) {
//Do something here
});
Passport.jsは、セッションをサーバーに保存するためうまく機能しません(不良でスケーラブルではありません)。サーバーにセッションデータを格納する(ステートレスのままにする)ことは望ましくありません。クラスターをスケールアップし、より多くのリクエストを処理できるからです。
Passport.jsライブラリのコードを見ると、それほど多くはありません。実際に自分でビルドすると、より高速で効率的になります。
既存のすべてのセッションを確認する方法はわかりませんが、PassportはセッションIDの発行を処理しています。ログイン後にテストエンドポイントにreq.userがあることを確認してください