Passportのローカル戦略を機能させようとしています。
このミドルウェアをセットアップしました:
passport.use(new LocalStrategy(function(username, password, done) {
//return done(null, user);
if (username=='ben' && password=='benny'){
console.log("Password correct");
return done(null, true);
}
else
return done(null, false, {message: "Incorrect Login"});
}));
しかし、ここで
app.use('/admin', adminIsLoggedIn, admin);
function adminIsLoggedIn(req, res, next) {
// if user is authenticated in the session, carry on
if (req.isAuthenticated())
return next();
// if they aren't redirect them to the home page
res.redirect('/');
}
常に失敗し、ホームページにリダイレクトされます。
なぜこれが起こっているのかわかりませんか?なぜ認証されないのですか?
私のコンソールでは、Password Correct
は印刷中です。なぜ機能しないのですか?
同様の問題がありました。パスポートに必要なエクスプレスセッションミドルウェアが原因である可能性があります。次の順序でミドルウェアを使用して修正しました:(Express 4)
var session = require('express-session');
// required for passport session
app.use(session({
secret: 'secrettexthere',
saveUninitialized: true,
resave: true,
// using store session on MongoDB using express-session + connect
store: new MongoStore({
url: config.urlMongo,
collection: 'sessions'
})
}));
// Init passport authentication
app.use(passport.initialize());
// persistent login sessions
app.use(passport.session());
これは、クライアントのPOST/GET呼び出しの問題でもある可能性があります。私はこれとまったく同じ問題を抱えていましたが、fetch
(これは私が使用していたものです)オプションcredentials:'include'
そのようです:
fetch('/...', {
method: 'POST',
headers: myHeaders,
credentials: 'include',
body: ...
...})
その理由は、フェッチはcookieの受け渡しをサポートしていないためです。これはこの場合に必要です。
私の問題は、データがhttpsでなくてもcookie.secureをtrueに設定したことです。
app.use(require('express-session')({
secret: process.env.sessionSecret,
cookie: {
maxAge: 1000 * 60 * 60 * 24 * 7 // 1 week
},
store: store,
resave: false,
saveUninitialized: false,
cookie: { secure: false } // Remember to set this
}));
Httpsを使用していない場合は、Cookieを必ずfalseに設定してください
cookie: { secure: false } // Set to false
また、httpsがあると思われる場合は、プロキシを信頼することを忘れないでください
app.set('trust proxy', 1) // trust first proxy
追加するのを忘れて同じ問題が発生しました
request.login()
に
app.post('/login',
function(request, response, next) {
console.log(request.session)
passport.authenticate('login',
function(err, user, info) {
if(!user){ response.send(info.message);}
else{
request.login(user, function(error) {
if (error) return next(error);
console.log("Request Login supossedly successful.");
return response.send('Login successful');
});
//response.send('Login successful');
}
})(request, response, next);
}
);
うまくいけば、私と同じ理由でここにたどり着いた他の人たちにも役立つかもしれません。
Passport.jsには、誰も実際に言及していないが、私は見つけました。これが、アカウントを作成するかサインインでき、最初は正常に認証されますが、後でreq.user
がundefined
であるか、req.isAuthenticated()
がfalse
であることがわかる理由ですアプリ。
認証後、passport.jsではリダイレクト/リダイレクトする必要があります。これが、パスポートが実際のセッションを初期化する方法です。
signIn(req, res, next) {
passport.authenticate("local")(req, res, function() {
if (!req.user) {
console.log("User not found!");
} else {
res.redirect("/")
console.log("signed in")
}
})
}
認証後に再ルーティングしないと、req.user
としてセッションを開始することさえできず、req.isAuthenticated()
はfalseになります。
私のアプリはReactおよびNodeアプリですが、これはNodeアプリとReact/Nodeアプリの両方に当てはまります。
ルートを次のようにラップする場合:
module.exports = function(){
router.get('/',(req,res)=>{
res.send('stuff');
}
}
次のようにルートに「アプリとパスポート」を渡す必要があります。
module.exports = function(app,passport){
//routes n stuff
}
passport.deserializeUserを修正して、この問題を修正しました。私はmongo nativeを使用していますが、ほとんどの例ではMongooseを使用しているため、再び_idトラップに陥りました。
したがって、deserializeUserでユーザーを読み取るときに、_idをmongo ObjectIDにすることを忘れないでください
passport.deserializeUser(function(user, done) {
const collection = db.get().collection('users')
const userId = new mongo.ObjectID(user);
collection.findOne({_id : userId}, function(err, user) {
if (err) done(err, null);
done(null, user);
});
});
IdをObjectIDにせず、どこにもエラーが表示されなかったため、クエリはユーザーを見つけませんでした。
私も同じ問題を抱えていて、ウェブ上で解決策を見つけることができませんでしたが、私はそれを見つけました。
app.use(require("express-session")({
secret: "This is the secret line",
resave: false,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(bodyParser.urlencoded({extended: true}));
エクスプレスセッションの要件と使用は、他の使用の前に行う必要があります。これを試してみてください、これがうまくいくと確信しています、私のために働いた!!
ログインが発生していても、同じ問題に直面しました。私がした間違いは、パスポートを初期化する前にミドルウェアisLoggedInを呼び出すことでした。そのため、コードを記述する順序は非常に重要です。順序が正しい順序で記述されていることを確認してください。私は次の順序で書いた
app.use(require('express-session')({
secret:'short' ,
resave:false,
saveUninitialized:false,
cookie:{secure:false}
}))
app.use(passport.initialize())
app.use(passport.session())
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); }
if (user.password!=password) { return done(null, false); }
return done(null, user);
});
}
))
passport.serializeUser(User.serializeUser())
passport.deserializeUser(User.deserializeUser())
app.use(isLoggedIn);
私も同じ問題に直面していましたが、@ PVThomasは、Answersのように解決策を提供します。私の問題は、findById()
のdeserialize()
メソッドにありました。 findOne()
でfindById()
を使用していましたが、それをfind()
に置き換えたところ、req.isAuthenticated()
は正常に動作しています。私のアプリはreq.session.passport.user
を保存していませんでした-ndefinedを返していましたが、findOne()
をfind()
に置き換えた後、req.session.passport.user
にユーザーIDを保存しています。