护照本地策略没有被调用

Oli*_*ain 40 node.js express passport.js

我确定我错过了一些非常明显的东西,但我无法弄明白.当提交登录表单时,我传递给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'));
});
Run Code Online (Sandbox Code Playgroud)

我的/登录页面上的表单是从护照文档中剪切并粘贴的,除了我将其更改为/ 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>
Run Code Online (Sandbox Code Playgroud)

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

GET /login 200 5ms - 432b
POST /auth 401 6ms
Run Code Online (Sandbox Code Playgroud)

请注意,永远不会记录"本地策略调用".

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

Arj*_*hta 72

我最近遇到了这个问题,它可能是由许多事情引起的.首先要检查的是确保bodyParser设置为express,我知道你已经完成了.

app.use(express.bodyParser());
Run Code Online (Sandbox Code Playgroud)

接下来要确保您提交给路径的表单包含usernameAND password,并且用户还必须在两个字段中输入内容.我在测试时难以进行一些测试而没有在密码字段中放置任何东西:) Passport要求BOTH执行传递给的LocalStrategy验证函数passport.authenticate('local').

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

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

其他

您是否尝试在/auth路线中添加请求处理程序?

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

要么

app.post('/auth', passport.authenticate('local', { successRedirect: '/', failureRedirect: '/auth' }));
Run Code Online (Sandbox Code Playgroud)

  • 我刚刚遇到了BOTH字段所需要的问题,非常感谢你指出这一点,我刚刚失去了一个小时,这可能会更长. (6认同)
  • 如果您使用的是最新版本,则不推荐使用bodyParser().我使用了bodyParser.urlencoded({extended:true}),它运行得很好. (4认同)

Jak*_*eba 27

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

router.post("/",
 function(req,res,next){
   passport.authenticate("local", function(err, user, info){

    // handle succes or failure

  }); 
})
Run Code Online (Sandbox Code Playgroud)

router.post("/",
 function(req,res,next){
   passport.authenticate("local", function(err, user, info){

    // handle succes or failure

  })(req,res,next); 
})
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你让我意识到passport.authenticate()返回一个函数! (3认同)
  • 你刚刚头疼了.谢谢! (2认同)

use*_*109 16

当您使用不同的用户名,密码输入字段而不是默认字段时,您将获得401.你必须在你的LocalStrategy中提供这样的:

passport.use(new LocalStrategy({
    usernameField: 'login',
    passwordField: 'password'
  },

  function(username, password, done) {
  ...
  }
));
Run Code Online (Sandbox Code Playgroud)

默认是username,password我认为.请参阅此处的文档.

  • 我正在努力解决这个问题,我发现在本地护照中,中间件正在查看req并试图查看req.body,当我在console.log未定义时 - 这会返回"错误消息错误"从来没有解决我的帖子.基本上认证甚至没有发生 (3认同)

Fan*_*ung 8

我认为您提交的表单中包含用户名或密码字段为空.

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


Fla*_*dre 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
Run Code Online (Sandbox Code Playgroud)

cf https://github.com/expressjs/body-parser


小智 5

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

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

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

    // your login goes here
    })
Run Code Online (Sandbox Code Playgroud)

);

如果有人愿意,我可以使用 mongodb 和本地护照为电话号码编写整个身份验证程序。

谢谢@user568109