【问题标题】:passport local strategy not getting called护照本地策略没有被调用
【发布时间】:2013-09-12 11:26:53
【问题描述】:

我确定我在这里遗漏了一些非常明显的东西,但我无法弄清楚这一点。当登录表单被提交时,我传递给 LocalStrategy 构造函数的函数不会被调用。

代码:

var express = require('express');
var http = require('http');
var path = require('path');
var swig = require('swig');
var passport = require('passport');

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

passport.serializeUser(function(user, done) {
  console.log('Serialize user called.');
  done(null, user.name);
});

passport.deserializeUser(function(id, done) {
  console.log('Deserialize user called.');
  return done(null, {name: 'Oliver'});
});

passport.use(new LocalStrategy(
  function(username, password, done) {
    console.log('local strategy called with: %s', username);
    return done(null, {name: username});
  }));

var app = express();

app.set('port', process.env.PORT || 3000);
app.set('view engine', 'swig');
app.set('views', __dirname + '/views');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser('asljASDR2084^^!'));
app.use(express.session());
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
app.use(require('less-middleware')({ src: __dirname + '/public' }));
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.errorHandler({ dumpExceptions:true, showStack:true }));

app.engine('swig', swig.renderFile);

app.post('/auth', passport.authenticate('local'));
app.get('/login', function(req, res) {
  // login is a simple form that posts username and password /auth
  res.render('login', {});
});

http.createServer(app).listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});

我的 /login 页面上的表单是从护照文档中剪切和粘贴的,只是我将其更改为提交到 /auth 而不是 /login:

<form action="/auth" 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>

当我 sumit 登录表单时,会记录以下内容

GET /login 200 5ms - 432b
POST /auth 401 6ms

请注意,“本地策略调用”永远不会被记录。

为什么我传递给 LocalStrategy 的函数没有被调用?

【问题讨论】:

    标签: node.js express passport.js


    【解决方案1】:

    我最近遇到了这个问题,它可能是由多种原因引起的。首先要检查的是确保 bodyParser 设置为 express,我看到你已经完成了。

    app.use(express.bodyParser());
    

    接下来要确保您提交给路由的表单同时包含usernamepassword用户还必须在这两个字段中输入内容。我对它进行了一些测试而感到困惑,并且在测试时实际上并没有在密码字段中输入任何内容 :) Passport 需要 BOTH 才能执行传递给 passport.authenticate('local') 的 LocalStrategy 验证功能。

    您的示例似乎也设置为正确捕获用户名和密码,但无论如何,您应该尝试测试即使没有护照也可以正确解析正文:

    app.post('/auth', function(req, res){
      console.log("body parsing", req.body);
      //should be something like: {username: YOURUSERNAME, password: YOURPASSWORD}
    });
    

    否则

    您是否尝试将请求处理程序添加到您的 /auth 路由?

    app.post('/auth', passport.authenticate('local'), function(req, res){
      console.log("passport user", req.user);
    });
    

    app.post('/auth', passport.authenticate('local', { successRedirect: '/', failureRedirect: '/auth' }));
    

    【讨论】:

    • 我不再有这个代码来测试所以我不确定,但我认为我上面的代码正在做你建议的所有事情。我的 /auth 路线与您的路线略有不同,因为我的本地策略负责返回结果,而您的本地策略将本地策略称为中间件,然后调用第二个函数来返回结果,但我不认为应该很重要。如果我再次尝试使用 Passport,我会再次查看这篇文章。
    • 当然!我想我一开始很难让它工作,因为我不太了解它,但一旦它启动并运行,它就是一个非常有用的库。
    • 我刚刚遇到了 BOTH fields required 的问题,非常感谢您指出这一点,我刚刚为此浪费了一个小时,而且可能会更长。
    • 谢谢!经过几个小时的挠头,它不起作用。添加 bodyParser 对我有用。
    • 如果您使用的是最新版本,不推荐使用 bodyParser()。我使用了 bodyParser.urlencoded({extended:true}) 并且效果很好。
    【解决方案2】:

    我在设置自己的路由处理程序时遇到了同样的问题,我从中调用了passport.authenticate()。我忘记了 passport.authenticate 返回必须调用的中间件,因此仅调用 passport.authenticate 是不够的。然后我换了

    router.post("/",
     function(req,res,next){
       passport.authenticate("local", function(err, user, info){
    
        // handle succes or failure
    
      }); 
    })
    

    router.post("/",
     function(req,res,next){
       passport.authenticate("local", function(err, user, info){
    
        // handle succes or failure
    
      })(req,res,next); 
    })
    

    【讨论】:

    • 谢谢你让我意识到passport.authenticate()返回一个函数!
    • 谢谢,我试试你的代码。这是工作,但我找不到 req.body 或 req.id。我的方法 router 是 get (router.get('/',...)
    • 太好了,我从示例中复制了代码,但错过了这个小细节(尽管我已经多次使用快递甚至护照)谢谢 1e+6!
    • 我遇到了同样的问题,但使用的是 Koa 而不是 express。必须将 Koa 上下文作为参数传递给返回的函数。
    【解决方案3】:

    当您使用不同于默认的用户名、密码输入字段时,您会得到 401。您必须像这样在 LocalStrategy 中提供:

    passport.use(new LocalStrategy({
        usernameField: 'login',
        passwordField: 'password'
      },
    
      function(username, password, done) {
      ...
      }
    ));
    

    我认为默认是usernamepassword。请参阅文档here

    【讨论】:

    • 感谢您的想法,但我不认为就是这样。实际上,我将这些文档中的表单剪切并粘贴到我的登录页面中,所以我很确定我已经正确命名了这些字段。我会更新我的问题以包含该信息。
    • 我目前正在努力解决这个问题,我发现在本地护照内部,中间件正在查看 req 并试图查看 req.body,当我 console.log 未定义时——这会返回一个“错误消息错误”,它永远不会为我的帖子解决。基本上验证甚至没有发生
    • @Catalyst req.body 应该由 bodyParser 中间件设置。
    • 啊!非常感谢!我在表格中有电子邮件。他们应该更清楚地提到它,或者至少管理文档,以便他们提供额外的对象来立即设置这些参数,而不是使用默认实现。
    【解决方案4】:

    我认为您提交的用户名或密码字段为空。

    如果您填写两个输入然后提交,LocalStrategy 将被调用。

    【讨论】:

      【解决方案5】:

      对于 Express 4.x:

      // Body parser
      var bodyParser = require('body-parser');
      
      app.use(bodyParser.urlencoded({ extended: false })) // parse application/x-www-form-urlencoded
      app.use(bodyParser.json()) // parse application/json
      

      参考https://github.com/expressjs/body-parser

      【讨论】:

        【解决方案6】:

        我也为同样的问题头疼了几个小时。正如其他答案所告诉的那样,我已经准备好了一切,例如 1. 表单正在返回所有字段。 2. body 解析器设置正确,extended:true 3. Passport 与每个设置和配置。

        但我已经用电话号码和密码更改了用户名字段。通过更改如下代码解决了我的问题

          passport.use('login', new LocalStrategy(
            {usernameField:'phoneNumber',
            passwordField:'password'},
            function (username, password, done) {
        
            // your login goes here
            })
        

        );

        如果有人愿意,我可以使用 mongodb 和 passport-local 编写电话号码的整个身份验证过程。

        谢谢@user568109

        【讨论】:

          【解决方案7】:

          我的问题是,我有 enctype='multipart/form-data'。只需将其更改为 multipart='urlencoded'。我认为这会解决它。

          【讨论】:

          • 谢谢!即将从头开始编写我自己的身份验证。为我节省了大量时间。由于某种原因,Passport "passport": "^0.3.2", "passport-http": "^0.3.0", "passport-local": "^1.0.0", 的这个包组合不适用于登录表单中的 enctype='multipart/form-data' 属性。
          【解决方案8】:

          要同时捕获usernamepassport,请确保添加:

          app.use(express.urlencoded());
          

          就我而言,我使用的是app.use(express.json());,并从&lt;form&gt; 发布用户名和密码。

          【讨论】:

            【解决方案9】:

            可能您的请求格式不正确(尤其是请求的正文),并且您的用户名和密码未按您的预期发送。

            这是一个 API 调用包装器的示例,它强制将您的请求正文解析为 json:

            Api = {};
            Api.request = (route, options) => {
              options = options || {};
            
              options.method = options.method || 'GET';
              options.credentials = 'include';
            
              if (options.method === 'POST') {
                options.headers = {
                  'Accept': 'application/json',
                  'Content-Type': 'application/json',
                };
                options.body = JSON.stringify(options.data) || '{}';
              }
            
              fetch(absoluteUrl + '/api/' + route, options)
                .then((response) => response.json())
                .then(options.cb || (() => {}))
                .catch(function(error) {
                  console.log(error);
                });
            };
            

            可以这样使用:

            Api.request('login', {
              data: {
                username: this.state.username,
                password: this.state.password
              },
              method: 'POST',
              cb: proxy((user) => {
                console.log(user);
              }, this)
            });
            

            【讨论】:

              【解决方案10】:

              对我来说,一切都已正确设置。问题是我正在收集表单数据,然后从表单数据创建一个 json 并将其像 JSON.stringify(formdatajson) 一样发送到服务器。 (对我来说,登录表单是屏幕上的一个弹出窗口)

              我通过调试passportjs发现了我的错误...

              如果您也有同样的问题,并且上述解决方案似乎都不适合您,请调试 passportjs。

              打开

              strategy.js
              

              将调试器放在下面的方法中。

              Strategy.prototype.authenticate 
              

              检查将为您提供哪些表单数据。 希望对您有所帮助...

              【讨论】:

                【解决方案11】:
                1. npm install passport-local

                2. var 护照 = 要求('护照') , LocalStrategy = require('passport-local').Strategy;

                根据passportjs.org,它对我有用!

                【讨论】:

                  【解决方案12】:

                  还有另一种可能性:对我来说,我不小心在我的 body-parser 中间件之前定义了我的路由,所以 body-parser 从来没有为登录路由激活。

                  【讨论】:

                    【解决方案13】:

                    希望总是有人 - 就我而言,这是我尝试在 cookieParser 和 express-session 之前使用护照中间件的事实 这是我的代码:

                    passportConfig(app);
                    app.use(cookieParser());
                    app.use(session({ secret: 'bla' }));
                    

                    将passportConfig更改为关闭并且它起作用了:

                    app.use(cookieParser());
                    app.use(session({ secret: 'bla' }));
                    passportConfig(app);
                    

                    【讨论】:

                      【解决方案14】:

                      对我来说它不起作用,因为我在我的登录表单中设置了不同的 name 在我的 passport.js 中,当我将 serializeUser 中的 user.name 更改为 @ 时,它对我有用987654322@.

                      passport.serializeUser(function (user, done) {
                          done(null, user.username)
                      })
                      
                      passport.deserializeUser(function (username, done) {
                          Users.findOne({
                              username: username
                          }).then((user) => {
                              if (!user) {
                                  return done(new Error("No such user"))
                              }
                              return done(null, user)
                          }).catch((err) => {
                              done(err)
                          })
                      })

                      【讨论】:

                        【解决方案15】:

                        如果您在表单或输入类型中包含 name 属性并且它对应于传递给 localStrategy 回调函数的参数,请在视图中检查您的表单。

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 2019-07-02
                          • 1970-01-01
                          • 2019-03-19
                          • 2016-05-29
                          • 2016-10-12
                          • 1970-01-01
                          • 1970-01-01
                          相关资源
                          最近更新 更多