Express4和护照:无法进行身份验证

时间:2015-02-17 22:35:23

标签: javascript node.js authentication passport.js passport-local

我正在学习javascript和node.js.如您所知,任何节点应用程序中最重要的部分之一是登录模块,因此我开始使用护照和本地护照,但我无法理解护照的确切身份。我对护照认证过程的理解如下:

'use strict';

var express = require('express');
var app = express();
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var dbConfig = require('./settings/db.js');
var mongoose = require('mongoose');
var expressSession = require('express-session');
var flash = require('connect-flash');

mongoose.connect(dbConfig.url);

app.use(expressSession({
  secret: 'mySecretKey'
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());

var server = app.listen(3000, function() {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Admin app started at: %s %s ', host, port);
});

passport.serializeUser(function(user, done) {
  console.log('serializing user!');
  done(null, 'Hi');
});

passport.deserializeUser(function(id, done) {
  console.log('deserializing user');
  done(null, {
    '_id': 'Hi',
    'username': 'shankhs',
    'password': 'admin'
  });
});

var isAuthenticated = function(req, res, next) {
  if (req.isAuthenticated()) {
    console.log('Authenticated');
    console.log(req);
    next();
  }
  console.log('redirecting to /');
  console.log(req.isAuthenticated());
  res.redirect('/');
};

app.get('/', function(req, res, next) {
  var fileOptions = {
    root: __dirname,
    dotfiles: 'deny',
    headers: {
      'x-timestamp': Date.now(),
      'x-sent': true
    }
  };
  res.sendFile('login.html', fileOptions, function(err) {
    if (err) {
      console.log(err);
      res.status(err.status).end();
    } else {
      console.log('send login.html!' + Date.now());
    }
  });
});

app.get('/admin', isAuthenticated, function(req, res, next) {
  var fileOptions = {
    root: __dirname,
    headers: {
      'x-timestamp': Date.now(),
      'x-sent': true
    }
  };
  var fileName = 'index.html';
  res.sendFile(fileName, fileOptions, function(err) {
    if (err) {
      console.log(err);
      res.status(err.status).end();
    } else {
      console.log('Send index.html' + Date.now());
    }
  });
});

passport.use('login', new LocalStrategy(
  function(req, username, password, done) {
    console.log('using passport!');
    console.log(req.body.username);
    console.log(req.body.password);
    done(null, {
      '_id': 'Hi',
      'username': 'shankhs',
      'password': 'admin'
    });
  }
));

app.post('/login', function(req, res) {
  console.log(req.params);
  passport.authenticate('login', {
    successRedirect: '/admin',
    failureRedirect: '/',
    failureFlash: true
  })
});
  1. 对/ login路由的post请求调用async passport.authenticate call。
  2. 此passport.authenticate采取"策略"作为一个论点
  3. 调用此策略,返回另一个' done'异步调用(在我的情况下)没有错误和用户对象
  4. 完成后' call,serializeUser被调用,页面被重定向到/ admin
  5. 如果有任何后续请求或任何具有isAuthenticated钩子的url被调用,则passport.initialize会检查req.passport.user对象是否为空。
  6. 如果为空,则再次重复验证过程。
  7. 如果不是,passport.session会调用passport.deserializeUser来创建req.user对象
  8. 我的问题如下:

    1. 在' login'策略,这三个永远不会记录:

      console.log('使用护照!'); 的console.log(req.body.username); 的console.log(req.body.password);

    2. 这是否意味着我的登录'策略永远不会被称为?

      1. 同样,从不调用serializeUser和deserializeUser中的console.logs。那么这些功能也没有被调用?
      2. 如果我对护照库的理解是正确的,我是否缺少任何要打电话的功能?

        由于

1 个答案:

答案 0 :(得分:4)

对于未来的战士:

这就是护照的运作方式。有关护照如何运作的详细说明是here

这里缺少的是调用/ login后的bodysarser。您可能认为护照知道如何解析req.body!错误!它没有! Express v 4以后的body-parser必须独立安装并用作:

var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
  extended: true
}));

在帖子请求中:

app.post('/login', function(req, res, next) {
  console.log('in login post!');
  console.log('body parsing: ' + req.body.username + ' ' + req.body.password);
  passport.authenticate('login', function(err, user, info) {
    if (err) {
      console.log('passport err: ' + err);
      return next(err);
    }
    if (!user) {
      console.log('no user found!');
      return res.redirect('/');
    }
    req.logIn(user, function(err) {
      if (err) {
        console.log('login error: ' + err);
        return next(err);
      }
      return res.redirect('/admin');
    });
  })(req, res, next);
});

正如您所看到的,我编写了一个自定义的logIn回调函数,它比successRedirect和failureRedirect更有意义且易于调试。如果没有body-parser,自定义函数就无法工作,因为护照不知道如何解析req.body。

护照的api医生应该提到这个!那么,既然一切都按预期运作,那么世界现在就有意义了!