2014-04-02 9 views
5

Próbuję użyć passport.js w mojej aplikacji node.js do uwierzytelnienia użytkownika za pomocą MongoDB. Nigdy nie osiągnąłem sukcesu.Paszport-lokalne zwraca błąd 400, nigdy nie pyta o bazę danych

W poście, mogę wysłać "e-mail": "[email protected]", "hasło": "test"

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


app.post('/login', 
    passport.authenticate('local', { successRedirect: '/', 
           failureRedirect: '/fail' }) 
); 

passport.use(new LocalStrategy({ 
     emailField: 'email', 
     passwordField: 'passw', 
    }, 
function (emailField, passwordField, done) { 
    process.nextTick(function() { 
     db.collection(users, function (error, collection) { 
     if (!error) { 
      collection.findOne({ 
       'email': emailField, 
       'password': passwordField 
      }, function (err, user) { 
       if (err) { 
        return done(err); 
       } 
       if (!user) { 
        console.log('this email does not exist'); 
        return done(null, false); 
       } 
        return done(null, user); 
      }); 
     } else { 
      console.log(5, 'DB error'); 
     } 
     }); 
    }); 
})); 

W kolekcji MongoDB 'użytkownicy':

{ 
    "_id": { 
     "$oid": "533b5283e4b09d8a1148b4c4" 
    }, 
    "email": "[email protected]", 
    "password": "test" 
} 

Może nie mam połączenia z bazą danych, nie jestem pewien.

Ponadto, gdy loguję się w całej funkcji, nie otrzymuję żadnych dzienników. Po prostu otrzymuję

Wszelkie sugestie będą mile widziane. Myślę, że może mi brakować czegoś, ale nie jestem pewien, jak to zorganizować. W innej funkcji gdzie piszę do bazy muszę używać:

var uristring = 
process.env.MONGOLAB_URI || 
process.env.MONGOHQ_URL || 
'mongodb://<myurlhere>'; 

mongo.connect(uristring, function (err, db) { 

Oto zaktualizowany kod

wymagając te:

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

użyciu tych :

// all environments 
app.set('port', process.env.PORT || 3000); 
app.set('views', path.join(__dirname, 'views')); 
app.set('view engine', 'ejs'); 
app.use(express.favicon()); 
app.use(express.logger('dev')); 
app.use(express.json()); 
app.use(express.urlencoded()); 
app.use(express.methodOverride()); 
app.use(express.cookieParser()); 
app.use(express.session({ secret: 'keyboard cat'})); 
app.use(logfmt.requestLogger()); 
app.use(express.static(path.join(__dirname, 'public'))); 
app.use(passport.initialize()); 
app.use(passport.session()); 
app.use(app.router); 

// User authentication passport 

passport.use(new LocalStrategy(
    { 
     usernameField: 'email', 
     passwordField: 'passw', 
    }, 
    function (userId, password, done) { 
     // removed process.nextTick 
     console.log('Hey! no more 400 error!'); 
     db.collection(users, function (error, collection) { 
      if (!error) { 
       collection.findOne({ 
        'email': userId, 
        'password': password 
       }, function (err, user) { 
        if (err) { 
         return done(err); 
        } 
        if (!user) { 
         console.log('this email does not exist'); 
         return done(null, false); 
        } 
        return done(null, user); 
       }); 
      } else { 
       console.log(5, 'DB error'); 
      } 
     }); 
    } 
)); 

passport.serializeUser(function(user, done) { 
    done(null, user); 
}); 

passport.deserializeUser(function(user, done) { 
    done(null, user); 
}); 

app.post('/login', passport.authenticate('local'), function(req, res) { 
    console.log('SUCCESS WOOOO'); 
    // If this function gets called, authentication was successful. 
    // `req.user` contains the authenticated user. 
    //res.redirect('/users/' + req.user.username); 
    }); 

Ten kod zawsze daje mi POST /login 400 10ms podczas wysyłania do/logowania. Wszystkie moje inne trasy działają dobrze.

+0

Czy Twój kod znajduje się w jednym pliku, czy jest podzielony na moduły? Pytam, ponieważ kolejność, w której dzwonisz, może mieć znaczenie. Również, opuściłeś 'process.nextTick' w swoim kodzie z konkretnego powodu? Sądzę, że w przykładowym kodzie "kpią" z opóźnienia wywołania DB, ale w rzeczywistości nie jest on potrzebny. –

+0

Nie, właśnie uruchomiłem tę aplikację i obecnie ta funkcja jest w app.js. Planuję przełamanie tego, czyniąc to bardziej modularnym po tym, jak uruchomię uwierzytelnianie. – Joel

+0

Próbowałem tak wielu rzeczy. Obecnie otrzymuję 404. 'app.post ('/ login', passport.authenticate ('local'), function (req, res) {' 'console.log ('SUCCESS WOOOO');' '// Jeśli ta funkcja zostanie wywołana, uwierzytelnianie powiodło się. ' // req.user zawiera uwierzytelnionego użytkownika. " ' //res.redirect('/users/ '+ req.user.username); ' '});' – Joel

Odpowiedz

1

To okazało się problemem z listonoszem (z którego korzystałem wiele razy bez problemu).

Kiedyś użyłem prawdziwej formy html, działało dobrze. Może coś na nagłówki?

+0

Mam podobne problemy z listonoszem. Nawet przy włączonym rozszerzeniu Interceptor nie wydaje się utrzymywać żadnego pojęcia trwałości sesji (poprzez pliki cookie). –

17

1) bał HTTP 400 error

Paszport zgłasza błąd HTTP 400, gdy nazwa użytkownika i/lub hasło nie są ustawione.

Zobacz źródło około linii 75, gdzie Strategy.prototype.authenticate zgłasza błąd 'missing credentials'.

2) Diagnozowanie przyczyn

w kodzie, masz blok:

passport.use(new LocalStrategy({ 
     emailField: 'email', 
     passwordField: 'passw', 
    }, 

Ale emailField nie jest rozpoznawany przez paszportu. Powrót na source code, widzimy, że paszport poszukuje:

this._usernameField = options.usernameField || 'username'; 
this._passwordField = options.passwordField || 'password'; 

Dlatego HTTP 400 jest wyrzucane w tej konkretnej sytuacji.

4) Ustalenie problemu

Mam edytowano oryginalny kod do tego, co uważam, że będzie działać (lepiej) niż w oryginale. Zrobiłem trochę wolności podczas edycji, aby usunąć process.nextTick i zmieniono nazwę kilku rzeczy. Mam nadzieję, że jesteś osobą wybaczającą.:)

passport.use(new LocalStrategy(
    { 
     usernameField: 'email', 
     passwordField: 'passw', 
    }, 
    function (userId, password, done) { 
     // removed process.nextTick 
     console.log('Hey! no more 400 error!'); 
     db.collection(users, function (error, collection) { 
      if (!error) { 
       collection.findOne({ 
        'email': userId, 
        'password': password 
       }, function (err, user) { 
        if (err) { 
         return done(err); 
        } 
        if (!user) { 
         console.log('this email does not exist'); 
         return done(null, false); 
        } 
        return done(null, user); 
       }); 
      } else { 
       console.log(5, 'DB error'); 
      } 
     }); 
    } 
)); 

5) Kilka uwag zamknięcia:

  • Można też edytować atrybuty wejście forma pasuje do oczekiwanych wartości domyślne paszportach. Aby uzyskać wskazówki, patrz passport documentation.
  • Nie mogę zagwarantować, że połączenie MongoDB będzie działało, ale powinno to doprowadzić do przekroczenia HTTP 400. Jeśli wywołanie bazy danych powoduje problemy, jest to prawie na pewno nowe pytanie, ponieważ zaangażowany jest inny zestaw kodów i modułów.
  • Podczas korzystania z paszportu warto odwiedzić stronę projektu GitHub i przeczytać źródła. Często w źródle są komentarze, że (a) nie znajdują się w innych dokumentach lub (b) są blisko kodu, który opisują ... więc rzeczy są dla ciebie wyjaśnione, nawet jeśli nie jesteś guru kodującym lub czymkolwiek.
+0

Ciągle dostaję 400. Gdybym mógł przekroczyć 400, prawdopodobnie mógłbym to zrozumieć. Nadal nie mogę uzyskać żadnych dzienników, oprócz 400. Zaktualizowałem oryginalny wpis z moimi zmianami. 'POST/login 400 10ms' – Joel

+0

Publikuję na http: // localhost: 3000/login. Wszystkie moje inne trasy działają. Wysyłam wiadomość e-mail i hasło – Joel

+0

Skopiowałem prawie wszystko, co opublikowałeś, w jednostronicową aplikację opartą na lokalnym przykładzie na potrzeby paszportu i mongo. Jedyny przypadek, w którym mogę go uzyskać do 400, to fakt, że atrybuty w formularzu logowania nie zgadzają się z oczekiwaniami paszportu. Przepraszam, nie mogę zrobić więcej. Jeśli się zorientujesz, byłbym zainteresowany usłyszeniem tego, co się stało. –