简体   繁体   中英

.isAuthenticated() always false || passport local strategy

There are many similar posts to this one, but I haven't found a qualifying solution in any of the answers to those posts that have helped me with this.

the code

"use strict";

require('dotenv').config();

const auth     = require('./auth.js');

const express       = require('express');
const passport      = require('passport');
const bcrypt        = require('bcrypt');
const mongo         = require('mongodb');
const session       = require('express-session');
const cors          = require('cors');
const util          = require('util');

const app  = express();
const port = process.env.PORT || 8080;

app.use(cors());
app.use(express.json());
app.use(express.urlencoded({extended:true}));

app.use(session({
  secret: process.env.SESSION_SECRET,
  resave: true,
  saveUninitialized: true,
  cookie: {
    secure: false,
    maxAge: 1000 * 60 * 60 * 24 * 7
  }
}));

app.use(passport.initialize());
app.use(passport.session());

mongo.connect(process.env.DATABASE, {useNewUrlParser: true, useUnifiedTopology: true}, (err, db) => {
  if (err) {
    console.log('Database error: ' + err);
  } else {
    console.log('Database connection successful');

    auth(app, db);

    app.route('/test').get((req, res) => {
      res.send('The connection works!')
    });

    const ensureAuthenticated = (req, res, next) => {
      console.log('isAuth() is: ' + req.isAuthenticated());
      console.log('session store: ' + util.inspect(req.session, {showHidden: false, depth: null}));
      if (req.isAuthenticated()) return next();
      res.send('user not authenticated, begone! >:(');
    }

    app.route('/profile').get(
      ensureAuthenticated,
      (req, res) => {
        res.render({username: req.user.username});
      }
    );

    app.post('/login', 
      (request, response, next) => {
        console.log(request.session)
        passport.authenticate('local', 
        (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);
      }
    );

    app.route('/register').post((req, res, next) => {
      const hash = bcrypt.hashSync(req.body.password, 13);
      db.db().collection('users').findOne({username: req.body.username}, (err, user) => {
        if (err) {
          next(err);
        } else if (user) {
          res.send('user already exists :(');
        } else {
          db.db().collection('users').insertOne({
            username: req.body.username,
            password: hash
          },
            (err, doc) => {
              if (err) {
                res.send('registration mongo error');
              } else {
                next(null, user);
              }
            }
          )
        }
      })
    },
      passport.authenticate('local', {failureMessage: 'passport authenticate failure'}),
      (req, res, next) => {
        console.log('registration successful');
        req.logIn(req.user, err => {
          if (err) next(err)
          return console.log("i'm trying: " + req.user);
        });
        res.send('registration successful!!! :D');
      }
    );

    app.listen(port, () => {console.log(`Listening on port: ${port}`)});
  }
});

auth.js

const passport      = require('passport');
const LocalStrategy = require('passport-local');
const ObjectID      = require('mongodb').ObjectID;
const bcrypt        = require('bcrypt');

module.exports = (app, db) => {
  passport.use(new LocalStrategy(
    (username, password, done) => {
      db.db().collection('users').findOne({username: username}, (err, user) => {
        console.log(`${username} attempted to log in`);
        if (err) return done(err);
        if (!user) return done(null, false);
        if (!bcrypt.compareSync(password, user.password)) return done(null, false);
        console.log('local strategy successful');
        return done(null, user);
      })
    }
  ));

  passport.serializeUser((user, done) => {
    console.log(user.username + " serialized");
    done(null, user._id);
  });

  passport.deserializeUser((id, done) => {
    db.db().collection('users').findOne(
      {_id: new ObjectID(id)},
      (err, doc) => {
        done(null, doc);
      }
    );
  });
}

The Question:

All of the functions work just fine, I get all of the success return messages, and even register saves the user to the database, and login loads it successfully from the database. The only problem I'm having is that req.isAuthenticated() in the function ensureAuthenticated is always returning false, and as you can see, I really really really need it to be true so I can send the information to the client for the /profile route, and do all the other things I need with Passport. What am I missing?

Solution: I needed to add credentials: true to cors(), and something similar to the http headers ( withCredentials:true for axios) in the client. I'm adding this because I know somebody is going to have this same problem one day, and will probably have as hard of a time finding this answer as I did.

Extra: In most forums that I asked this question in, the answers I got were all people not believing that this code works, and patronizing me by telling me I need to re-learn passport and react (if I got an answer at all lmao).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM