web-dev-qa-db-ja.com

パスポートのreq.isAuthenticatedは、ハードコードが完了した場合でも常にfalseを返します(null、true)

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は印刷中です。なぜ機能しないのですか?

36
CodyBugstein

同様の問題がありました。パスポートに必要なエクスプレスセッションミドルウェアが原因である可能性があります。次の順序でミドルウェアを使用して修正しました:(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());
44
Nitin

これは、クライアントのPOST/GET呼び出しの問題でもある可能性があります。私はこれとまったく同じ問題を抱えていましたが、fetch(これは私が使用していたものです)オプションcredentials:'include' そのようです:

fetch('/...', {
  method: 'POST',
  headers: myHeaders,
  credentials: 'include',
  body: ...
  ...})

その理由は、フェッチはcookieの受け渡しをサポートしていないためです。これはこの場合に必要です。

8
Alex H

私の問題は、データが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
4
Thomas Lindauer

追加するのを忘れて同じ問題が発生しました

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);
    }
);

うまくいけば、私と同じ理由でここにたどり着いた他の人たちにも役立つかもしれません。

3
ozgeneral

Passport.jsには、誰も実際に言及していないが、私は見つけました。これが、アカウントを作成するかサインインでき、最初は正常に認証されますが、後でreq.userundefinedであるか、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アプリの両方に当てはまります。

1
Christian Reyes

ルートを次のようにラップする場合:

module.exports = function(){

router.get('/',(req,res)=>{
 res.send('stuff');
  }

}

次のようにルートに「アプリとパスポート」を渡す必要があります。

module.exports = function(app,passport){

//routes n stuff

}
0
metal_jacke1

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にせず、どこにもエラーが表示されなかったため、クエリはユーザーを見つけませんでした。

0
Mikko

私も同じ問題を抱えていて、ウェブ上で解決策を見つけることができませんでしたが、私はそれを見つけました。

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}));

エクスプレスセッションの要件と使用は、他の使用の前に行う必要があります。これを試してみてください、これがうまくいくと確信しています、私のために働いた!!

0
karan525

ログインが発生していても、同じ問題に直面しました。私がした間違いは、パスポートを初期化する前にミドルウェア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); 
0

私も同じ問題に直面していましたが、@ PVThomasは、Answersのように解決策を提供します。私の問題は、findById()deserialize()メソッドにありました。 findOne()findById()を使用していましたが、それをfind()に置き換えたところ、req.isAuthenticated()は正常に動作しています。私のアプリはreq.session.passport.userを保存していませんでした-ndefinedを返していましたが、findOne()find()に置き換えた後、req.session.passport.userにユーザーIDを保存しています。

0