web-dev-qa-db-fra.com

passeport stratégie locale ne se fait pas appeler

Je suis sûr que je manque quelque chose de vraiment évident ici, mais je ne peux pas le comprendre. La fonction que j'ai transmise au constructeur LocalStrategy n'est pas appelée lorsque le formulaire de connexion est soumis.

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

Le formulaire sur ma page/login est coupé et collé à partir des documents de passeport sauf que je l'ai changé pour le soumettre à/auth au lieu de/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>

Lorsque je soumets le formulaire de connexion, les éléments suivants sont enregistrés

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

Notez que la "stratégie locale appelée" n'est jamais enregistrée.

Pourquoi la fonction que j'ai transmise à LocalStrategy n'est-elle pas appelée?

39
Oliver Dain

J'ai récemment rencontré ce problème et il peut être causé par un certain nombre de choses. La première chose à vérifier est de s'assurer que le bodyParser est configuré pour express, ce que je vois que vous avez fait.

app.use(express.bodyParser());

La prochaine chose consiste à s'assurer que le formulaire que vous soumettez à l'itinéraire contient à la fois un username ET password, et l'utilisateur doit également entrer quelque chose dans les deux champs. J'étais perplexe pour un peu le tester et ne pas vraiment mettre quoi que ce soit dans le champ du mot de passe pendant le test :) Le passeport nécessite les DEUX pour exécuter la fonction de vérification LocalStrategy passée à passport.authenticate('local').

Votre exemple semble également être configuré pour capturer correctement le nom d'utilisateur et le mot de passe, mais dans tous les cas, vous devriez essayer de tester que le corps est analysé correctement même sans passeport:

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

Sinon

Avez-vous essayé d'ajouter un gestionnaire de demandes à votre itinéraire /auth?

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

ou

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

J'ai rencontré le même problème lorsque j'ai configuré mon propre gestionnaire d'itinéraire à partir duquel j'ai appelé passport.authenticate (). J'ai oublié que passport.authenticate renvoie un middleware qui doit être invoqué, il ne suffit donc pas d'appeler passport.authenticate. Puis j'ai remplacé

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

    // handle succes or failure

  }); 
})

avec

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

    // handle succes or failure

  })(req,res,next); 
})
25
Jakub Kutrzeba

Vous obtenez 401 lorsque vous utilisez des champs de saisie de nom d'utilisateur et de mot de passe différents de ceux par défaut. Vous devez fournir cela dans votre stratégie locale comme ceci:

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

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

La valeur par défaut est username et password je pense. Voir la documentation ici .

16
user568109

Je pense que vous soumettez le formulaire avec le champ nom d'utilisateur ou mot de passe vide.

Si vous remplissez les deux entrées puis soumettez, LocalStrategy sera appelé.

8
Fancyoung

Pour 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

J'ai aussi frappé ma tête pour le même problème pendant quelques heures. J'avais tout en place comme l'ont dit d'autres réponses comme 1. Le formulaire renvoyait tous les champs. 2. analyseur de corps a été configuré correctement avec étendu: vrai 3. Passeport avec chaque paramètre et configuration.

Mais j'ai changé le champ du nom d'utilisateur avec le numéro de téléphone et le mot de passe. En changeant le code comme ci-dessous, j'ai résolu mon problème

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

    // your login goes here
    })

);

Si quelqu'un veut, je peux écrire toute la procédure d'authentification pour le numéro de téléphone en utilisant mongodb et passeport-local.

Merci @ user568109

3
kamal pandey

Mon problème était que j'avais le enctype = 'multipart/form-data'. Changez simplement cela en multipart = 'urlencoded'. Et je pense que cela le résoudra.

3
Ognjen

Pour capturer à la fois username et passport assurez-vous d'ajouter:

app.use(express.urlencoded());

Dans mon cas, j'utilisais app.use(express.json()); et je publiais le nom d'utilisateur et le mot de passe de <form>.

0
A-Sharabiani
  1. npm installer un passeport-local

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

Selon passportjs.org et cela a fonctionné pour moi!

0
Mujtaba Zaidi

Il est possible que votre demande n'ait pas été correctement formatée (en particulier le corps) et que votre nom d'utilisateur et votre mot de passe n'aient pas été envoyés lorsque vous pensiez qu'ils l'étaient.

Voici un exemple de wrapper d'appel d'API qui applique votre corps de requête est analysé en tant que 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);
    });
};

Il peut être utilisé de cette façon:

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

Encore une autre possibilité: pour moi, j'avais accidentellement défini mes itinéraires avant mon middleware body-parser, donc body-parser n'était jamais actif pour la route de connexion.

0
Nenotlep

Pour moi, tout était correctement configuré. Le problème était que je collectais des données de formulaire, puis je créais un json à partir de données de formulaire et l'envoyais comme JSON.stringify (formdatajson) au serveur. (Pour moi, le formulaire de connexion était une fenêtre contextuelle à l'écran)

J'ai trouvé mon erreur en déboguant passportjs ...

Si vous avez également le même problème et qu'aucune des solutions ci-dessus ne semble fonctionner, déboguez passportjs.

ouvert

strategy.js

mettez le débogueur dans la méthode ci-dessous.

Strategy.prototype.authenticate 

Vérifiez quelles données du formulaire vous parviennent. J'espère que cette aide ...

0
ifti