2016-05-23 11 views
0

Ich versuche, PassportJS zu verwenden, um bestimmte Routen einer Webanwendung zu schützen. Ich besuche Passport, ExpressJS und MongoDB. Ich stelle fest, dass nach einer scheinbar erfolgreichen Authentifizierung jeder Versuch, auf eine dieser geschützten Routen zuzugreifen, erneut auf /login umgeleitet wird, als ob die Anmeldung fehlgeschlagen wäre.Warum leitet PassportJS mich weiter an failureRedirect?

Ich habe versucht, ein neues Projekt zu machen nur diesen Teil, um zu versuchen und zu testen und ich das gleiche Verhalten bekommen: Es gibt eine /authenticated Route, die den Benutzer angemeldet sein muss, und eine /unauthenticated eine, die doesn t. Nach erfolgreicher Anmeldung über die POST-Route /login sollte der Benutzer an /authenticated weitergeleitet werden; Wenn die Protokollierung nicht erfolgreich war, wurden sie zurück an /login umgeleitet.

Allerdings wird der Benutzer nach korrekter Umleitung auf /authenticated zurück zu /login umgeleitet!

screenshoot showing the redirects

Was kann ich hier falsch tun vielleicht? Der Benutzer wurde erfolgreich angemeldet. Warum werden sie zurück zu failureRedirect umgeleitet?

Alle relevanten Code ist in this GitHub repository. Ich werde als nächstes die server.js Datei und das Anmeldeformular sind:

<form action="/login" method="post"> 
    <label for=login_name>username</label> 
    <input type="text" name="username"><br/> 
    <label for=password>password</label> 
    <input type="password" name="password"><br/> 
    <input type="submit" value="Go"> 
</form> 

Dies ist die Express-Konfiguration:

app.set('port', (process.env.PORT || 3004)); 

app.use(function(req, res, next) { 
    res.setHeader('Access-Control-Allow-Origin', '*'); // Permissive CORS header 
    res.setHeader('Cache-Control', 'no-cache'); 
    res.header("Access-Control-Allow-Origin", "*"); 
    res.header('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS'); 
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); 
    next(); 
}); 

app.use(morgan('combined')); 
app.use(cookieParser()); 
app.use(bodyParser.json()); 
app.use(bodyParser.urlencoded({extended: true})); 
app.use(session({ secret: 'keyboard cat', resave: false, saveUninitialized: false })); 
app.use(passport.initialize()); 
app.use(passport.session()); 

Hier ist der Passport-Setup:

function verify (username, password, done) { 

    db.collection("users").findOne({ username: username }) 
    .then(
    doc => { 
     if (!doc) { 
     console.log(`User ${username} doesn't exist`); 
     done(null, false, { message: "User doesn't exist" }); 
     } 
     if (doc.password != password) { 
     console.log(`${password} is the wrong password`); 
     done(null, false, { message: "Wrong password" }); 
     } 
     else { 
     console.log("AOK"); 
     done(null, doc); 
     } 
    }, 
    reason => done(reason) 
); 
} 

passport.use(new LocalStrategy(verify)); 

passport.serializeUser(function(user, done) { 
    console.log("Serialize here, got " + JSON.stringify(user)); 
    done(null, user._id); 
}); 
passport.deserializeUser(function(id, done) { 
    db.collection("users").findOne({ _id: id }) 
    .then(
    doc => done(null, doc), 
    reason => done(reason) 
); 
}); 

Und diese sind meine Routen:

app.get("/login", (req, res) => { 
    fs.readFile("./login.html", "utf8", (err, data) => { 
    if (err) throw err; 
    res.send(data); 
})}); 

app.post("/login", passport.authenticate("local", { 
    failureRedirect: '/login', 
}), (req, res) => { res.redirect("/authenticated")}); 

var ensureLoggedIn = require('connect-ensure-login').ensureLoggedIn("/login"); 
app.get("/authenticated", ensureLoggedIn, (req, res) => res.send("o hai")); 
app.get("/unauthenticated", (req, res) => res.send("o hai")); 

app.listen(app.get('port'),() => { 
    console.log('Server started: http://localhost:' + app.get('port') + '/'); 
}); 

Auch t iese sind die Versionen jeder Bibliothek Ich verwende:

"dependencies": { 
    "body-parser": "^1.15.1", 
    "connect-ensure-login": "^0.1.1", 
    "connect-flash": "^0.1.1", 
    "cookie-parser": "^1.4.2", 
    "express": "^4.13.4", 
    "express-session": "^1.13.0", 
    "mongodb": "^2.1.19", 
    "morgan": "^1.7.0", 
    "passport": "^0.3.2", 
    "passport-local": "^1.0.0", 
    "path": "^0.12.7" 
    }, 

PD: ich nur mit Klartext-Passwörter für diesen kleinen Test, und nirgendwo in der Nähe einer Produktion DB.

+0

Funktioniert es, wenn Sie 'id' zu einem' ObjectId' konvertieren in 'deserializeUser'? 'db.collection (" Benutzer "). findOne ({_id: mongodb.ObjectId (id)})' – robertklep

+0

Sie haben Recht. Ich musste das nie tun, und ich habe tatsächlich andere Anrufe bei 'findOne', die ohne das perfekt funktionieren. Ich habe nicht bemerkt, dass 'deserializeUser' nicht funktionierte. Wenn Sie wollen, machen Sie eine vollständige Antwort, die ich akzeptieren kann. Danke vielmals! – jesusiniesta

+0

Verwenden Sie vielleicht Mungo? Mongoose wird Strings automatisch in ObjectId umwandeln, aber Ihre Abfrage in 'deserializeUser()' verwendet MongoDB direkt. – robertklep

Antwort

1

deserializeUser() wird die id als String übergeben, aber für die direkte MongoDB Abfragen gegen _id müssen Sie es zu einem ObjectId erste konvertieren:

passport.deserializeUser(function(id, done) { 
    db.collection("users").findOne({ _id: mongodb.ObjectId(id) }) 
    .then(
    doc => done(null, doc), 
    reason => done(reason) 
); 
}); 
Verwandte Themen