web-dev-qa-db-ja.com

パスポートのローカル戦略が呼び出されない

ここでは本当に明らかなものが欠けていると確信していますが、これを理解することはできません。 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ページのフォームはパスポートドキュメントからカットアンドペーストされますが、/ loginではなく/ authに送信するように変更した点が異なります。

<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に渡した関数が呼び出されないのはなぜですか?

39
Oliver Dain

私は最近この問題に遭遇しましたが、それは多くの事柄によって引き起こされる可能性があります。最初に確認することは、bodyParserがエクスプレス用に設定されていることを確認することです。

_app.use(express.bodyParser());
_

次に、ルートに送信するフォームにusername AND passwordおよびユーザーが両方のフィールドに何かを入力する必要があるの両方が含まれていることを確認します。私はそれを少しテストすることに困惑し、テスト中にパスワードフィールドに実際には何も入れませんでした:) Passportは、passport.authenticate('local')に渡されたLocalStrategy検証関数を実行するためにBOTHを必要とします.

また、ユーザー名とパスワードの両方を適切にキャプチャするように設定されているようですが、いずれにしても、パスポートがなくても本文が適切に解析されていることをテストしてみてください。

_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' }));
_
72
Arjun Mehta

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); 
})
25
Jakub Kutrzeba

デフォルトとは異なるユーザー名、パスワード入力フィールドを使用すると、401になります。次のようにLocalStrategyでそれを提供する必要があります:

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

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

デフォルトはusernamepasswordだと思います。ドキュメントを参照してください here

16
user568109

ユーザー名またはパスワードのフィールドが空の状態でフォームを送信すると思います。

両方の入力を入力して送信すると、LocalStrategyが呼び出されます。

8
Fancyoung

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

4
Flaudre

また、同じ問題で数時間頭を打ちました。 1のような他の回答が示すように、すべてを適切に配置していました。フォームはすべてのフィールドを返していました。 2.ボディパーサーは、extended:trueで正しくセットアップされました。3.すべての設定および構成のパスポート。

しかし、私は電話番号とパスワードでユーザー名フィールドを変更しました。以下のようなコードを変更することで私の問題を解決しました

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

    // your login goes here
    })

);

誰かが望むなら、mongodbとpassport-localを使用して電話番号の認証手順全体を書くことができます。

ありがとう@ user568109

3
kamal pandey

私の問題は、enctype = 'multipart/form-data'だったことです。それをmultipart = 'urlencoded'に変更するだけです。そして、それで解決すると思います。

3
Ognjen

usernamepassportの両方をキャプチャするには、必ず以下を追加してください。

_app.use(express.urlencoded());
_

私の場合、app.use(express.json());を使用しており、_<form>_からユーザー名とパスワードを送信していました。

0
A-Sharabiani
  1. npm install passport-local

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

passportjs.org によると、それは私のために働いた!

0
Mujtaba Zaidi

リクエストが適切にフォーマットされていない可能性があり(特に本文)、ユーザー名とパスワードが送信されたと思われるときに送信されていない可能性があります。

以下は、リクエスト本文がjsonとして解析されることを強制するAPI呼び出しラッパーの例です。

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
maxhud

さらに別の可能性:私にとっては、ボディパーサーミドルウェアの前に誤ってルートを定義していたため、ボディパーサーはログインルートに対してアクティブになりませんでした。

0
Nenotlep

私にとっては、すべてが適切にセットアップされていました。問題は、フォームデータを収集し、フォームデータからJSONを作成し、JSON.stringify(formdatajson)のようにサーバーに送信することでした。 (私にとって、ログインフォームは画面上のポップアップでした)

Passportjsをデバッグして間違いを見つけました...

同じ問題があり、上記の解決策のいずれも機能していない場合は、passportjsをデバッグします。

開いた

strategy.js

以下のメソッドにデバッガを配置します。

Strategy.prototype.authenticate 

どのフォームデータがあなたのために来ているかを確認してください。このヘルプを願っています...

0
ifti