it-swarm.com.de

passport-local mit node-jwt-simple

Wie kann ich passport-local kombinieren, um bei erfolgreicher Authentifizierung ein JWT-Token zurückzugeben?

Ich möchte node-jwt-simple verwenden und sehe passport.js . Ich bin mir nicht sicher, wie ich vorgehen soll.

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

passport.use(new LocalStrategy(
  function(username, password, done) {
    User.findOne({ username: username }, function(err, user) {
      if (err) { return done(err); }
      if (!user) {
        return done(null, false, { message: 'Incorrect username.' });
      }
      if (!user.validPassword(password)) {
        return done(null, false, { message: 'Incorrect password.' });
      }
      return done(null, user);
    });
  }
));

Ist es möglich, das Token zurückzugeben, wenn done () aufgerufen wird? So etwas wie das ... (nur Pseudo-Code)

if(User.validCredentials(username, password)) {
  var token = jwt.encode({username: username}, tokenSecret);
  done(null, {token : token}); //is this possible?
}

Wenn nicht, wie kann ich den Token zurückgeben?

87
cgiacomi

Ich habe es herausgefunden!

Zunächst müssen Sie die richtige Strategie implementieren. In meinem Fall LocalStrategy und Sie müssen Ihre Validierungslogik angeben. Lassen Sie uns zum Beispiel den in passport-local verwenden.

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

passport.use(new LocalStrategy(
  function(username, password, done) {
    User.findOne({ username: username }, function(err, user) {
      if (err) { return done(err); }
      if (!user) {
        return done(null, false, { message: 'Incorrect username.' });
      }
      if (!user.validPassword(password)) {
        return done(null, false, { message: 'Incorrect password.' });
      }
      return done(null, user);
    });
  }
));

durch den Rückruf zur Bestätigung, den Sie function(username, password, done) geben, wird sichergestellt, dass Ihr Benutzer gefunden und überprüft wird, ob das Kennwort übereinstimmt (außerhalb des Bereichs der Frage und meiner Antwort).

passport.js erwartet, dass mehrere Teile funktionieren. Zum einen geben Sie den Benutzer in die Strategie zurück. Ich habe versucht, diesen Teil des Codes zu ändern, und das war falsch. Der Rückruf erwartet false, wenn die Validierung fehlschlägt, und einen object (den validierten Benutzer), wenn Sie erfolgreich sind.

Nun ... wie kann man JWT integrieren?

In Ihrer Login-Route müssen Sie eine erfolgreiche oder eine erfolglose Authentifizierung durchführen. Und hier müssen Sie die JWT-Token-Erstellung hinzufügen. Wie so:

(Denken Sie daran, die Sitzung zu deaktivieren, da Sie andernfalls die Funktionen zum Serialisieren und Deserialisieren implementieren müssen. Diese Funktionen werden nicht benötigt, wenn Sie die Sitzung nicht fortsetzen. Dies ist nicht der Fall, wenn Sie eine tokenbasierte Authentifizierung verwenden.)

Aus passportlokalen Beispielen: (mit dem hinzugefügten JWT-Token)

// POST /login
//   This is an alternative implementation that uses a custom callback to
//   achieve the same functionality.
app.post('/login', function(req, res, next) {
  passport.authenticate('local', function(err, user, info) {
    if (err) { return next(err) }
    if (!user) {
      return res.json(401, { error: 'message' });
    }

    //user has authenticated correctly thus we create a JWT token 
    var token = jwt.encode({ username: 'somedata'}, tokenSecret);
    res.json({ token : token });

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

Und das ist alles! Wenn Sie nun/login und POST Benutzername und Passwort (sollten immer über SSL sein) aufrufen, versucht der erste obige Codeausschnitt, einen Benutzer auf der Grundlage des von Ihnen angegebenen Benutzernamens zu finden, und überprüft dann, ob Passwort-Übereinstimmungen (Natürlich müssen Sie dies an Ihre Bedürfnisse anpassen).

Danach wird Ihre Login-Route aufgerufen und Sie können sich um die Rückgabe eines Fehlers oder eines gültigen Tokens kümmern.

Hoffe das wird jemandem helfen. Und wenn ich Fehler gemacht habe oder etwas vergessen habe, lass es mich wissen.

122
cgiacomi

Dies ist eine großartige Lösung, ich möchte nur Folgendes hinzufügen:

var expressJwt = require('express-jwt');

app.use('/api', expressJwt({secret: secret}));

Ich verwende gerne "express-jwt" , um das Token zu validieren.

übrigens: Dieser Artikel ist großartig, um zu lernen, wie man das Token auf der Clientseite mit Angular handhabt, um es bei jeder Anforderung zurückzusenden

https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/

18
ZeroCR

Hier ist eine Kesselplatte, an der ich gerade arbeite, um speziell nur API-Token zu verwenden (keine Sitzungen ... diese Sitzungen sind natürlich nicht schlecht; wir verwenden nur den Token-Ansatz): https://github.com/roblevintennis/passport-api-tokens

3
Rob