使用 express 配置 passport-local

Configure passport-local with express

我正在尝试将 passport-local 与 express 一起使用,这是我的配置:

App.js

var app = express();

app.use(require('morgan')('combined'));
app.use(require('cookie-parser')());
app.use(require('body-parser').urlencoded({ extended: true }));
app.use(require('express-session')({ secret: 'keyboard cat', resave: false, saveUninitialized: false }));

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

app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(session({
  secret: 'my super secret',
  resave: false,
  saveUninitialized: true
}));

index.js

var MongoClient = require('mongodb').MongoClient, assert = require('assert');
var session = require('express-session');
var passport = require('passport');
var localPassport = require('passport-local').Strategy;

var url = 'mongodb://localhost:27017/mydb';

var router = express.Router();

passport.use(new localPassport(
  function(username, password, cb) {
    console.log(">>>To evaluate : " + username);
    console.log(">>>To evaluate : " + password);
    MongoClient.connect(url, function(err, db) {
      db.collection('users').find({email: username, password: password, verified: true }, {_id=0, email=1, name = 1}).toArray(function(err, results){
        console.log("Fetching results!!!!");
        console.log(results);
        if(results.length >= 1){
          console.log("<<<returning true");
          return cb(null, results[0]);
        }else{
          console.log("<<<returning 00000");
          return cb(null, false);
        }
      });
    });
  }
));

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

passport.deserializeUser(function(id, cb) {
  db.users.findById(id, function (err, user) {
    if (err) { return cb(err); }
    cb(null, user);
  });
});


router.get('/invites', function(req, res, next) {
  require('connect-ensure-login').ensureLoggedIn(),
  console.log("~~~~~~ ~ ~~~~~ ~~~~~~~~Fetched!");
  console.log(req);
  res.render('invites.html');
});


router.post('/login', function(req, res, next) {
  //res.render('invites.html');
  //var auth = passport.authenticate('local', { failureRedirect: '/login' });
  passport.authenticate('local')(req, res, function () {
    console.log(">>>Auth: ");
    console.log(req);
            res.redirect('/invites');
        });

});

好的,让我解释一下代码: 代码执行没有问题,方法: passport.use(new localPassport 调用正确(我调试了变量),结果没问题

console.log("<<<returning true");
return cb(null, results[0]);

这些行显示在终端中(而不是其他行),那么我认为该方法没问题。

但是,当我尝试使用时:req.user 变量是 undefined。 我不确定为什么用户会话没有存储在请求中。

一些想法?

好吧,我终于解决了,这是一个非常粗糙的代码,但可以作为示例使用。

var express = require('express');
var passport = require('passport');
var Strategy = require('passport-local').Strategy;

var nodemailer = require('nodemailer');
const uuidV1 = require('uuid/v1');
var MongoClient = require('mongodb').MongoClient, assert = require('assert');
var moment = require('moment');
var session = require('express-session');
var passport = require('passport');
var localPassport = require('passport-local').Strategy;
var path = require('path');

var url = 'mongodb://localhost:27017/viraldb';


// Configure the local strategy for use by Passport.
//
// The local strategy require a `verify` function which receives the credentials
// (`username` and `password`) submitted by the user.  The function must verify
// that the password is correct and then invoke `cb` with a user object, which
// will be set at `req.user` in route handlers after authentication.
passport.use(new Strategy(
  function(username, password, cb) {
    username = username.toLowerCase();
    MongoClient.connect(url, function(err, db) {
      db.collection('users').find({email: username, password: password, verified: true }, {_id:0, email: 1, name:1, id: 1}).toArray(function(err, results){
        if(results.length >= 1){
          return cb(null, results[0]);
        }else {
          return cb(null, false);
        }
      });
    });


  }));



// Configure Passport authenticated session persistence.
//
// In order to restore authentication state across HTTP requests, Passport needs
// to serialize users into and deserialize users out of the session.  The
// typical implementation of this is as simple as supplying the user ID when
// serializing, and querying the user record by ID from the database when
// deserializing.
passport.serializeUser(function(user, cb) {
  cb(null, user.id);
});

passport.deserializeUser(function(id, cb) {
  MongoClient.connect(url, function(err, db) {
    db.collection('users').find({id: id, verified: true }, {_id:0, email: 1, name:1, id: 1}).toArray(function(err, results){
      if(results.length >= 1){
        return cb(null, results[0]);
      }else{
        return cb(null, false);
      }
    });
  });

});




// Create a new Express application.
var app = express();
app.use(express.static(path.join(__dirname, 'public')));

// Configure view engine to render EJS templates.
app.set('views', __dirname + '/views');
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'ejs');

// Use application-level middleware for common functionality, including
// logging, parsing, and session handling.
app.use(require('morgan')('combined'));
app.use(require('cookie-parser')());
app.use(require('body-parser').urlencoded({ extended: true }));
app.use(require('express-session')({ secret: 'keyboard cat', resave: false, saveUninitialized: false }));

// Initialize Passport and restore authentication state, if any, from the
// session.
app.use(passport.initialize());
app.use(passport.session());

// Define routes.
app.get('/', function(req, res) {
  res.render('index.html');
});

app.get('/login', function(req, res){
  res.render('login.html');
});

app.post('/login', passport.authenticate('local', { failureRedirect: '/login' }),
  function(req, res) {
    res.redirect('/invites');
});

app.get('/logout', function(req, res){
  req.logout();
  res.redirect('/login');
});

app.get('/invites', function(req, res){
  if(req.user == null || req.user.email == null || req.user.email == "")
    res.redirect('/login');

  res.render('invites.html');
});

app.get('/myinvites', function(req, res){
  MongoClient.connect(url, function(err, db) {
    db.collection('users', function(err, collection) {
      collection.find({invitatedby: req.user.email}).sort({verified: 1}).toArray(function(err, results){
          res.json(results);
      });
    });
  });

});

app.get('/myprofile', function(req, res){
  MongoClient.connect(url, function(err, db) {
    db.collection('users', function(err, collection) {
      collection.find({email: req.user.email}).toArray(function(err, results){
          res.json(results);
      });
    });
  });
});

app.get('/validate', function(req, res){
  var code = req.query.code;

  MongoClient.connect(url, function(err, db) {
      db.collection('users').count({code: code, expired: false, verified: false }, function(err, results){
        res.json({success: (results >= 1)  });
      });
  });
});

app.get('/register', function(req, res){
  var code = req.query.code;

  var code = req.query.code;
  var firstname = req.query.firstname;
  var lastname = req.query.lastname;
  var password = req.query.password;
  var name = firstname + " " + lastname;

  MongoClient.connect(url, function(err, db) {
      db.collection('users').count({code: code, expired: false, verified: false }, function(err, results){
        if(results >= 1) {
          db.collection('users').update({code: code, expired: false, verified: false}, {$set:{name: name, password: password, expired: true, verified:true, code: "" }}, function(err, results){
            return res.json({success: true, message: ""});
          });
        }else{
          return res.json({success: false, message: "Invalid code."});
        }
      });
  });
});

app.get('/sendInvitation', function(req, res){
  var email = req.query.email.toLowerCase();
  var guid = uuidV1().split("-")[0].toUpperCase();

  var today = moment();
  var tomorrow = moment(today).add(1, 'day');
  var rid = generateRandom();

  MongoClient.connect(url, function(err, db) {
    db.collection('users').count({email: email, invitatedby: req.user.email, expired: false}, function(err, results){
      if(results > 0){
        res.json({success: false, message: "You already invited this user"});
      }else{

        db.collection('users').count({email: email, verified: true}, function(err, results){
          if(results > 0){
            res.json({success: false, message: "This email is already registered. Please try with a new one."});
          }else{

            db.collection('users').insertOne({
                "name" : "",
                "email" : req.query.email,
                "code" : guid,
                "invitatedby": req.user.email,
                "invitationdate": moment(today).format('YYYY-MM-DDTHH:mm:ss') + ".000",
                "expired": false,
                "verified": false,
                "id": rid,
                "expireDate": moment(tomorrow).format('YYYY-MM-DDTHH:mm:ss') + ".000",
             }, function(err, result) {

               var transporter = nodemailer.createTransport({
                 host: "smtp-mail.outlook.com",
                 secureConnection: false,
                 port: 587,
                 tls: {
                    ciphers:'SSLv3'
                 },
                 auth: {
                     user: 'myhotmailemail@hotmail.com',
                     pass: 'myhotmailpass'
                 }
               });

               var mailOptions = {
                 from: '" ' + req.user.name + ' "<rivera5656@hotmail.com>',
                 to: email,
                 subject: "You've been invited to join " + req.user.name + "s team",
                 text: 'Hello world ',
                 html: "<p>I've been working behind the scenes on a new multiplayer game that's about to launch, and I thought that you might be interested in joining my team.</p><p>I just signed an NDA to get more info, and was given the ability to invite just 5 people, and I thought that you'd be a perfect fit.</p><p>You can check it out here:</p><p><a href='" + req.headers.host + "/agreement'>Click here to go to the site</a></p><p>Use this invite code to get in:  <b>" + guid + "</b></p><p>Fill out the NDA form, and then let me know what questions you have.</p><p>Thanks</p><p>John</p>" // html body
               };

               transporter.sendMail(mailOptions, function(error, info){
                 if(error){
                     return console.log(error);
                 }
                 console.log('Message sent: ' + info.response);
               });
               res.json({success: true, message: ""});
            });
          }
        });

      }
    });
  });
});

function generateRandom() {
    return parseInt(Math.random() *  3.1415926535897932384626433832795028841971 * (100000000000000));
}


app.get('/profile',
  require('connect-ensure-login').ensureLoggedIn(),
  function(req, res){
    res.render('profile', { user: req.user });
});

app.get('/account', function(req, res){
  res.render('account.html');
});

app.listen(3000);