【问题标题】:Why is my Passport auth function not executing when called within a route?为什么我的 Passport auth 函数在路由中调用时没有执行?
【发布时间】:2017-01-09 22:14:25
【问题描述】:

我正在使用 Passport 来保护 MEAN 堆栈应用程序的前端和后端。该应用程序的结构如下:

monstermash
    config // server configuration
    public // static directory that will serve the entire Angular frontend
    app
        index.js // initialization of the server
        models 
            index.js // mongoose schemas and models
        passport 
            index.js // configuration for passport and all my strategies
        routes 
            index.js // basic route definitions for the API (using functions defined under v1, below) and UI (routes defined inline here for simplicity's sake)
                v1
                    index.js // all the functions called to power the API routes

这里是app/index.js,因为我知道有时需要以正确的顺序调用应用程序中间件:

var express = require('express');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var session = require('express-session');
var mongoose = require('mongoose');
var app = express();
var CONFIG = require('config').BASE;
var bcrypt = require('bcrypt-nodejs');
var passport = require('passport');
var flash = require('connect-flash');
var models = require('./models');

app.passport = require('./passport');
app.port = CONFIG.PORT;
app.use(bodyParser.json()); 
app.use(bodyParser.urlencoded({
    extended: false
})); 
app.use(allowCrossDomain);
app.use(express.static('public'));
app.use(cookieParser());
app.use(session({ 
    secret: 'keyboard cat',
    resave: true,
    saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());

var routes = require('./routes');

app.use(express.static('public', {redirect:false}));
routes(app)

module.exports = app

passport/index.js 看起来像这样。很多被注释掉的部分只是为了调试而被删掉:

var models = require('../models')

passport = require('passport')
  , LocalStrategy = require('passport-local').Strategy
  , LocalAPIKeyStrategy = require('passport-localapikey-update').Strategy;

passport.use('localapikey', new LocalAPIKeyStrategy(
  {apiKeyHeader:'x-auth-token'},
  function(apikey, done) {
  console.log('api key');
    models.User.findOne({ apikey: apikey }, function (err, user) {
      if (err) { return done(err); }
      if (!user) { return done(null, false); }
      return done(null, user);
    });
  }
));

passport.use('local-signup', new LocalStrategy(
  function (req, username, password, done) {
    console.log('trying local');
    models.User.findOne({
      local: {username: username}, function (err, user) {
        if (err) {
          return done(err);
        }
        if (!user) {
          console.log('no user');
          return done (null, false);
        }

        if (!user.validPassword(password)) {
          console.log('bad pwd');
          return done(null, false);
        }
        return done (null, user);
      }
    })
  }
));

module.exports = passport;

此处包含 localaipkey 策略只是为了说明 的工作原理和配置方式与本地注册策略大致相同。

然后我的routes/index.js 看起来像这样。登录表单的 HTML 在这里是内联的,因为这只是一个初步测试。请注意,除了检查验证之外,我没有做任何事情。在此处包含一个 API 路由也确实演示了它是如何设置的。这里的 UI 代码直接来自 Passport 教程,因为我回到绘图板并摆脱了我自己的代码。

var v1 = require('./v1');

  // API routes as an example. This authentication is called before the route and works fine.

  module.exports = function(app) {
    /* API: V1 */
    app.route('/v1/monster/:id')
      .put(
        app.passport.authenticate('localapikey', { session: false }),
        v1.monster.update)
      .delete(
        app.passport.authenticate('localapikey', { session: false }),
        v1.monster.delete
      );

    // My test login routes. Here, authenticate is called inside the route because it's the handler for logging in.

    app.route('/login')
      .post(
        function (req, res) {
          console.log(req.body);
          app.passport.authenticate('local-signup', { 
            successRedirect: '/root',
            failureRedirect: '/fail'
          });
      })
      .get(function (req,res) {
        res.send('<!-- views/login.ejs -->\
          <!doctype html>\
          <html>\
          <head>\
              <title>Node Authentication</title>\
              <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css"> <!-- load bootstrap css -->\
              <link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css"> <!-- load fontawesome -->\
              <style>\
                  body        { padding-top:80px; }\
              </style>\
          </head>\
          <body>\
          <div class="container">\
          \
          <form action="/login" method="post">\
            <div>\
                <label>Username:</label>\
                <input type="text" name="username"/>\
            </div>\
            <div>\
                <label>Password:</label>\
                <input type="password" name="password"/>\
            </div>\
            <div>\
                <input type="submit" value="Log In"/>\
            </div>\
        </form>\
          \
          </div>\
          </body>\
          </html>');
      });

因此该表单提交带有表单数据的POST:/login 请求。表单主体在req.body 中,但我在验证功能中的console.log 消息从未被记录。表单提交只是挂了又挂了;这条路线上没有res.send(),因为身份验证应该通过或失败并且永远不会到达,但整个app.passport.authenticate() 功能完全被绕过了。

我对此进行了很多尝试和错误,我发现如果我使用甚至没有注册的策略名称调用app.passport.authenticate(),也会发生同样的事情:没有失败消息,它只是继续路由,就像它甚至不存在一样。所以也许问题在于这种情况正在发生,它没有识别出正在注册的local-signup 策略,尽管我不知道为什么会这样并且找到了localapikey 策略。

旁注,我实际上是在表单中设置了usernamepassword 来测试它;我从尝试空提交或无密码提交但没有看到他们的验证功能执行的人那里发现了一个 SO 问题,所以我确定不是这样。

【问题讨论】:

  • 进一步挖掘表明两件事:第一,app.passport.authenticate 中的passReqToCallback 选项似乎默认为true 而不是false,所以我的验证功能被称为错误,它应该是function (req, username, password, done) 二,app.passport.authenticate() 在路由函数之前调用时工作得很好,但在内部调用时似乎完全跳过。我认为这些可能是相关的,因为以前把它放在路由中的全部原因是让它访问req。我开始认为这些文档已经过时了。

标签: node.js express passport.js passport-local


【解决方案1】:

所以,我的问题的答案基本上是“因为您不能在路由内调用身份验证函数。”

我不会删除这个问题,因为我知道我从某个 Passport 教程中得到了这个想法,因此其他人可能会在以后成为同样事情的牺牲品。

【讨论】:

  • 如果由于某种原因指定的字段为空“”。该函数不会被调用。这可能是一个错误或设计。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-18
  • 2021-01-06
  • 2021-05-22
  • 1970-01-01
  • 2021-03-10
  • 2019-04-26
相关资源
最近更新 更多