簡體   English   中英

Express4和護照:無法驗證

[英]Express4 and passport: Unable to authenticate

我正在學習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路由的發布請求將調用異步password.authenticate調用。
  2. 這個passport.authenticate以“策略”作為參數
  3. 調用此策略將返回另一個“完成”的異步調用,並且(在我的情況下)沒有錯誤和用戶對象
  4. 在“完成”調用之后,調用serializeUser並將頁面重定向到/ admin
  5. 如果有任何后續請求或具有isAuthenticated鈎子的任何URL被調用,passport.initialize將檢查req.passport.user對象是否為空。
  6. 如果為空,則再次重復認證過程。
  7. 如果不是這樣,password.session將調用創建req.user對象的passport.deserializeUser。

我的問題如下:

  1. 在“登錄”策略中,這三個從未記錄:

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

那么這是否意味着我的“登錄”策略從未被采用?

  1. 同樣,從不調用serializeUser和deserializeUser中的console.logs。 因此,這些函數也不會被調用嗎?

如果我對護照庫的理解是正確的,我是否缺少任何要調用的功能?

謝謝

對於未來的戰士:

那就是護照應該如何工作的方式。 有關護照工作原理的詳細說明在這里

這里缺少的是/ login調用中的bodyparser。 您可能會認為護照知道如何解析req.body! 錯誤! 不會! Express v 4及更高版本的body解析器必須獨立安裝並用作:

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,自定義功能將無法工作,因為passport不知道如何解析req.body。

護照的api文件應提及這一點! 好吧,既然一切都按預期進行,那么現在世界就變得有意義了!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM