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?
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' }));
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);
})
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 .
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é.
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
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
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.
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>
.
npm installer un passeport-local
var passport = require ('passport'), LocalStrategy = require ('passport-local'). Strategy;
Selon passportjs.org et cela a fonctionné pour moi!
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)
});
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.
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 ...