2017-06-20 2 views
0

Ich baue eine Express-Js-API mit Reisepass js, und um benutzerdefinierte Fehler Messages als JSON formatiert werden kann ich benutze custom callbacks.Passport JS Benutzerdefinierte Rückruf genannt 3 mal

Wenn ich eine unbekannte E-Mail zur Verfügung stelle, wird der benutzerdefinierte Rückruf, den ich schrieb, 3 Mal aufgerufen, was zu Unhandled rejection Error: Can't set headers after they are sent. führt. Was macht Sinn.

Jede Hilfe wird geschätzt.

Hier ist meine Umsetzung:

Strategie:

const localLoginStrategy = new LocalStrategy({ 
    usernameField: "emailAddress" 
}, (emailAddress, password, done) => { 
    // Called once 
    User.findOne({ 
     where: { emailAddress } 
    }).then((existingUser) => { 
     // Called once 
     if (!existingUser) { return done(null, false, { message: "Invalid email/password combination", status: 401 }); } 

     return existingUser.comparePassword(password); 
    }).then((userData) => { 
     return done(null, userData); 
    }).catch((err) => { 
     return done(null, false, { message: "Invalid email/password combination", status: 401 }); 
    }); 
}); 

passport.use(localLoginStrategy); 

Express Middleware für die Authentifizierung mithilfe von benutzerdefinierten Rückruf:

const requireUsernamePassword = (req, res, next) => { 
    if(!req.body.emailAddress || !req.body.password) { 
     return res.status(400).json({ message: "No emailAddress and/or password provided" }); 
    } 
    // Called once 
    passport.authenticate("local", { session: false }, (err, user, info) => { 
     // Called three times! 
     console.log("authenticate callback") 
     if (!user || err) { 
      return res 
       .status(info.status || 400) 
       .json({ message: info.message || "Authentication error" }); 
     } 
     req.user = user; 
     return next(); 
    })(req, res, next); 
}; 
+0

Was ruft Ihre requireUsernamePassword-Middleware auf? Können die Mehrfachanrufe von früher im Call-Stack kommen? Könntest du versuchen, einen verrutschten User.findOne (....) hinzuzufügen? Ich bezweifle, dass es daraus kommt, aber es kann wehtun und es ist generell (nicht immer) gut, Versprechungen zurückzugeben. Haben Sie den Wert von err/user/info für jeden der 3 Anrufe protokolliert? – Boris

Antwort

1

Sie rufen die done Funktion mehrmals.

Ich glaube, wenn Sie return done(...) in der Methode then nennen, ist der nächste then wird done wieder aufrufen.

Deshalb ist Ihre callback Funktion von requireUsernamePassword mehr als pünktlich aufgerufen worden.

Ich hoffe, es hilft.

+0

Ich kämpfe immer mit Versprechen, obwohl ich es bis zum Zeitpunkt der Antwort herausgefunden habe, das ist die richtige Antwort. – Alexander

1

Zur Überprüfung Ihrer Pflichtfelder erstellen Sie eine generische Middleware, die das erforderliche Feld prüft und den entsprechenden Rückgabecode zurückgibt. Genau wie unten.

module.exports = function checkParams(params) { 
    params = params || []; 
    return function(req, res, next) { 
    var valid = true; 
    if(Array.isArray(params)) { 
     params.forEach(function(_param) { 
     valid = valid && !!req.body[_param]; 
     }); 
    } 
    if (valid) { next() } else {return res.status(400).end();} //this is for missing required parameters 
    }; 
}; 

Jetzt sagen wir zum Beispiel, Sie haben zwei APIs. Login und CreateUser. API Routen sollten sieht aus wie unten

app.post('/Login', checkParams(['emailAddress', 'password']), passport.authenticate('local', { failureRedirect: '/login' }), actualLoginMethod); 


app.post('/CreateUser', checkParams(['userName', 'Phone']), passport.authenticate('local', { failureRedirect: '/login' }), actualCreateUserMethod); 

Wenn eines dieser Parameter (Benutzername und Telefon in/AngelegtVon + emailaddress und Passwort in/Login) fehlt, dann wird es 400 Zustand zurück und beenden die Ausführung von diesem Punkt, Sie können Ändern Sie die Logik des checkParams nach Ihren Bedürfnissen.

Wenn die erforderlichen Parameter verfügbar sind, wird die lokale JWT-Strategie überprüft. Sobald eine Anfrage an beide Prüfpunkte erfolgt, ruft sie die aktuelle Methode auf.

Hoffe, das könnte Ihnen helfen.

+0

Ich mag deine Idee, aber es wäre das Problem, das ich hatte. Ich werde jedoch die Check-Params-Funktion implementieren. – Alexander

Verwandte Themen