简体   繁体   English

Express4和护照:无法验证

[英]Express4 and passport: Unable to authenticate

I am learning javascript and node.js. 我正在学习javascript和node.js。 As you know, one of the most important part of any node app is login module, so I started to play with passport and passport-local but I am not able to understand how exactly passport authenticates. 如您所知,任何节点应用程序中最重要的部分之一就是登录模块,因此我开始尝试使用护照和本地护照,但是我无法理解护照的身份验证方式。 My understanding of passport authentication process is below with the code: 我对护照认证过程的理解如下:

'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. A post request to /login route invokes async passport.authenticate call. 对/ login路由的发布请求将调用异步password.authenticate调用。
  2. This passport.authenticate takes a "strategy" as an argument 这个passport.authenticate以“策略”作为参数
  3. This strategy is invoked which returns another 'done' async call with (in my case) no error and user object 调用此策略将返回另一个“完成”的异步调用,并且(在我的情况下)没有错误和用户对象
  4. After the 'done' call, serializeUser is called and the page is redirected to /admin 在“完成”调用之后,调用serializeUser并将页面重定向到/ admin
  5. If there is any subsequent request or any url is called which has isAuthenticated hook, passport.initialize checks whether req.passport.user object is empty or not. 如果有任何后续请求或具有isAuthenticated钩子的任何URL被调用,passport.initialize将检查req.passport.user对象是否为空。
  6. If its empty, the authentication process is again repeated. 如果为空,则再次重复认证过程。
  7. If its not, passport.session calls passport.deserializeUser which creates the req.user object 如果不是这样,password.session将调用创建req.user对象的passport.deserializeUser。

My problem is as follows: 我的问题如下:

  1. In the 'login' strategy, these three are never logged: 在“登录”策略中,这三个从未记录:

    console.log('using passport!'); console.log('正在使用护照!'); console.log(req.body.username); console.log(req.body.username); console.log(req.body.password); console.log(req.body.password);

So does this mean my 'login' strategy is never called? 那么这是否意味着我的“登录”策略从未被采用?

  1. Similarly, console.logs in serializeUser and deserializeUser is never called. 同样,从不调用serializeUser和deserializeUser中的console.logs。 So these functions are also not getting called? 因此,这些函数也不会被调用吗?

If my understanding of the of passport library is correct, am I missing any function to call? 如果我对护照库的理解是正确的,我是否缺少任何要调用的功能?

Thanks 谢谢

For the future warriors: 对于未来的战士:

That is how passport is supposed to work. 那就是护照应该如何工作的方式。 Detailed explanation on how passport works is here 有关护照工作原理的详细说明在这里

The thing that is missing here is the bodyparser in the post call to /login. 这里缺少的是/ login调用中的bodyparser。 You might think passport knows how to parse req.body! 您可能会认为护照知道如何解析req.body! Wrong! 错误! It doesn't! 不会! Express v 4 onwards body-parser has to be installed independetly and used as : Express v 4及更高版本的body解析器必须独立安装并用作:

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

In the post request: 在发布请求中:

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

As you can see, I wrote a custom logIn callback function, which makes more sense and easily debuggable than just successRedirect and failureRedirect. 如您所见,我编写了一个自定义的logIn回调函数,它不仅比successRedirect和failureRedirect更有意义,而且易于调试。 Without the body-parser the custom function wont work because passport doesnt know how to parse req.body. 没有body-parser,自定义功能将无法工作,因为passport不知道如何解析req.body。

The api doc of passport should mention this! 护照的api文件应提及这一点! Well, now since everything works as intended, the world makes sense now! 好吧,既然一切都按预期进行,那么现在世界就变得有意义了!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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