node.js 护照本地策略没有被调用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18690354/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 15:33:31  来源:igfitidea点击:

passport local strategy not getting called

node.jsexpresspassport.js

提问by Oliver Dain

I'm sure I'm missing something really obvious here, but I can't figure this out. The function I've passed to the LocalStrategy constructor doesn't get called when the login form gets submitted.

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

Code:

代码:

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'));
});

The form on my /login page is cut and pasted from the passport docs except that I changed it to submit to /auth instead of /login:

我的 /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>

When I sumit the login form, the following gets logged

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

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

Note that "local strategy called" is never logged.

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

Why isn't the function I passed to LocalStrategy getting called?

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

回答by Arjun Mehta

I recently came across this problem and it can be caused by a number of things. First thing to check is ensuring that the bodyParser is set up for express, which I see that you have done.

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

app.use(express.bodyParser());

The next thing is ensuring that the form you are submitting to the route contains both a usernameAND password, and the user must also enter something in both fields. I was stumped for a bit testing it and not actually putting anything in the password field while testing :) Passport requires BOTH to execute the LocalStrategy verification function passed to passport.authenticate('local').

下一步是确保您提交给路由的表单包含usernameAND password并且用户还必须在这两个字段中输入一些内容。我对它进行了一些测试,但实际上并没有在测试时在密码字段中放入任何内容 :) Passport 需要 BOTH 来执行传递给passport.authenticate('local').

Your example also seems to be set up to capture both username and password properly, but in any case, you should try testing that the body is being parsed properly even without passport:

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

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


Else

别的

Did you try adding a request handler to your /authroute?

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

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

or

或者

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

回答by Jakub Kutrzeba

I encountered the same problem when I set up my own route handler from which I called passport.authenticate (). I forgot that passport.authenticate returns middleware that must be invoked, so just calling passport.authenticate isn't sufficient. Then I replaced

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

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

    // handle succes or failure

  }); 
})

with

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

    // handle succes or failure

  })(req,res,next); 
})

回答by user568109

You get 401 when you using different username, password input fields than the default ones. You have to provide that in your LocalStrategy like this :

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

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

  function(username, password, done) {
  ...
  }
));

Default is usernameand passwordI think. See the docs here.

默认是usernamepassword我认为。请参阅此处的文档。

回答by Fancyoung

I think you submit the form with username or password field empty.

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

If you fill both inputs then submit, LocalStrategy will be called.

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

回答by Flaudre

For Express 4.x:

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

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

回答by kamal pandey

I also banged my head for the same problem for few hours. I was having everything in place as told by other answers like 1. Form was returning all fields. 2. body parser was setup correctly with extended:true 3. Passport with every setting and configuration.

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

But i have changed username field with phoneNumber and password. By changing code like below solved my problem

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

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

    // your login goes here
    })

);

);

If anyone want i can write the whole authentication procedure for phonenumber using mongodb and passport-local.

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

Thanks @user568109

谢谢@user568109

回答by Ognjen

My problem was, that I had the enctype='multipart/form-data'. Just change that to multipart='urlencoded'. And I think that will solve it.

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

回答by ifti

For me everything was setup properly.. The issue was that I was collecting form data and then creating a json from form data and send it like JSON.stringify(formdatajson) to server. (For me login form was a popup on screen)

对我来说,一切都设置正确。(对我来说,登录表单是屏幕上的一个弹出窗口)

I Found my mistake by debugging passportjs...

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

If you also have same problem and none of the above solution seems working for you then debug passportjs.

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

open

打开

strategy.js

put debugger in below method.

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

Strategy.prototype.authenticate 

Check what form data is coming for you. Hope this help ...

检查为您提供的表单数据。希望这有助于...

回答by Mujtaba Zaidi

  1. npm install passport-local

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

  1. npm install 本地护照

  2. varpassport = require('passport') , LocalStrategy = require('passport-local').Strategy;

According to passportjs.organd it worked for me!

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

回答by maxhud

It's possible your request wasn't formatted properly (particularly the body of it) and your username and password weren't being sent when you thought they were.

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

Here is an example of an API call wrapper that enforces your request body is parsed as json:

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

It can be used this way:

它可以这样使用:

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