首页 文章

护照本地策略没有被调用

提问于
浏览
38

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

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

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

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

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

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

12 回答

  • 8

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

    app.use(express.bodyParser());
    

    接下来要确保您提交给路线的表格包含 username AND passwordand the user must also enter something in both fields . 我在测试时难以进行一些测试而没有在密码字段中放置任何东西:) 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}
    });
    

    Else

    您是否尝试在 /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' }));
    
  • 0

    当我设置自己的路由处理程序时,我遇到了同样的问题,我从中调用了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); 
    })
    
  • 4

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

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

    默认是 usernamepassword 我想 . 请参阅文档here .

  • 2

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

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

  • 0

    对于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
    

    C.F. https://github.com/expressjs/body-parser

  • 0

    几个小时后,我也为同样的问题猛烈抨击我 . 我正在通过其他答案告诉我所有的事情,例如1. Form返回所有领域 . 2.正确设置了body解析器,扩展名为:true 3.带有每个设置和配置的Passport .

    但我已经用phoneNumber和密码更改了用户名字段 . 通过更改下面的代码解决了我的问题

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

    );

    如果有人想我可以使用mongodb和passport-local为phonenumber编写整个身份验证过程 .

    谢谢@ user568109

  • 16

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

  • 2

    您的请求可能没有正确格式化(特别是它的正文),并且您的用户名和密码在您认为时没有被发送 .

    下面是一个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)
    });
    
  • 0

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

    我通过调试passportjs找到了我的错误......

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

    打开

    strategy.js
    

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

    Strategy.prototype.authenticate
    

    检查数据的形式 . 希望这有帮助......

  • 18
    • npm install passport-local

    • var passport = require('passport'),LocalStrategy = require('passport-local') . 策略;

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

  • 0

    还有另外一种可能性:对我来说,我在我的身体解析器中间件之前意外地定义了我的路线,因此身体解析器从未对登录路线有效 .

  • 67

    要捕获 usernamepassport ,请确保添加:

    app.use(express.urlencoded());
    

    在我的情况下,我使用 app.use(express.json()); 并从 <form> 发布用户名和密码 .

相关问题