2012-06-26 13 views
6

mam wiedzę z passport for node, ale nie ma rzeczy, takich jak:biblioteki uwierzytelniania node.js z tokenem „utrwalania” funkcjonalności

  • wytwarzające żeton „wytrwałość” (jak w authlogic/session/session.rb#L35
  • generowania nietrwałymi tokeny dla hasła resetuje
  • zapamiętaj funkcjonalności potrzebne
  • zarządzania tymi właściwości logowania/wylogowania na jakimś modelu klasy itp

Czy istnieją jakieś biblioteki, które rozwiązały to w społeczności Node.js? Jeśli istnieje coś tak solidnego (lub na drodze do bycia tak silnym) jak Devise for Rails, byłoby idealnie, ale wszystko, co rozwiązuje ten problem z tokenem, zadziała równie dobrze.

Szaloną rzeczą jest wiele przykładów na przechowywanie użytkownika id w sesji!

request.session['userId'] = user.get('id') 

To tylko prośba o zhackowanie.

To powinno być coś takiego:

require.session['persistenceToken'] = App.User.generateRandomToken() 
+0

Domyślam się, że nie jest to trudne do zrealizowania, wystarczy, że już istnieje. –

+0

Połączyłem strategię "zapamiętaj mnie": https://github.com/jaredhanson/passport-remember-me –

Odpowiedz

8

hasło jednorazowe (aka jednorazowego użytku żeton) Strategia dla resetowania hasła jest coś, co będę wykonawczych. Biorąc pod uwagę architekturę Passport, może to być osobny moduł i nie zdziwiłoby mnie, gdy dowiedziałem się, że ktoś już wdrożył takie rozwiązanie.

Pamiętaj, że funkcja obsługi tokenów trwałych to także coś, co chciałbym wesprzeć. Najlepiej, bym to była osobna strategia, ale może potrzebować jakiegoś podstawowego wsparcia. Jeśli tak się stanie, kilka dodatkowych linii w req.logIn (https://github.com/jaredhanson/passport/blob/master/lib/passport/http/request.js#L28) powinno być w stanie go pokryć.

Jeśli chodzi o przechowywanie identyfikatora użytkownika w sesji, nie widzę dużego ryzyka, ponieważ domyślnie w usłudze Connect/Express właściwości sesji są przechowywane w całości i sprawdzane przez unikatowy zestaw sid, który jest ustawiony w zaszyfrowanym pliku cookie. Złośliwy użytkownik musiałby posiadać zarówno unikalny sid, jak i sekret sesji w celu sfałszowania żądań.

Mozilla korzysta z usługi Passport w ramach zarządzania tożsamością, aby połączyć BrowserID z innymi dostawcami, którzy nie mają obsługi BrowserID (patrz browserid-bigtent). Biorąc pod uwagę ich wymagania, programiści mogą być pewni, że Passport spełnia surowe wymagania bezpieczeństwa.

(Ostatecznie serializacja sesji w usłudze Passport jest odpowiedzialnością aplikacji, więc zamiast bezpieczeństwa można użyć losowego tokena zamiast identyfikatora użytkownika, jeśli jest to pożądane ze względów bezpieczeństwa. Oczywiście należy to zrobić, jeśli dane są przechowywane bezpośrednio w pliku cookie, ale " d sugerują, że jest to najbardziej nieupoważnione podejście.)

Jeśli chodzi o zarządzanie tymi właściwościami w modelu, usługa Passport została zaprojektowana jako całkowicie agnostyczna dla modelu/ORM. Nie zamierzam nigdy zmieniać tego faktu, ponieważ uważam, że decyzje te najlepiej pozostawić aplikacji (a Paszport jest bardziej elastyczny w wyniku delegowania tej odpowiedzialności). Mimo to uważam, że jest miejsce na inne moduły, które można niezależnie budować na podstawie usługi Passport, aby zapewnić taką funkcjonalność.

Wszystko, co powiedziałem, myślę, że Passport jest najsolidniejszym z istniejących auth rozwiązań Node.js.Twoje pierwsze trzy prośby znacznie ułatwiłyby to zadanie i powinny być łatwe do zrealizowania. Chciałbym współpracować przy wprowadzaniu tych funkcji, więc nie wahaj się skontaktować ze mną.

Wreszcie, na wypadek, gdyby ktoś był ciekawy, uwierzytelnianie API pierwszej klasy jest obecnie w pracach, w oddziale authinfo. W oparciu o to, passport-http-oauth implementuje strategie serwera OAuth, które można łączyć z oprogramowaniem pośredniczącym oauthorize jako zestawem narzędzi do składania serwerów OAuth. To jeszcze nie jest w pełni upieczone, ale będzie to kolejna skuteczna funkcja Paszportu, gdy będzie gotowa.

+0

Używam paszportu z lokalną strategią uwierzytelniania i chciałbym dodać funkcjonalność Remember Me. Czy mogę w jakiś sposób ustawić czas życia ciasteczek w mojej funkcji serializeUser() Czy muszę zhakować rdzeń? Albo coś innego? – ragulka

2

W międzyczasie wystarczy coś takiego. Dostosuj, jeśli to konieczne, aby pasowała do Twojej aplikacji i żądanego czasu trwania plików cookie. Sprawdzanie nazwy użytkownika & Hasło to rodzaj tandetnego sposobu na wykrycie próby logowania, ale działa dobrze z paszportem.

app.use(function(req, res, next) { 
    if(
      typeof(req.body.username) !== "undefined" 
      && typeof(req.body.password) !== "undefined" 
      ) { 
     if(req.body.remember == 1) { 
      req.session.cookie.maxAge = 365*24*60*60*1000; 
     } 
     else { 
      req.session.cookie.maxAge = 24*60*60*1000; 
     } 
    } 
    next(); 
}); 
+0

Zastanawiam się, dlaczego ustawienie 'res.session.cookie.maxAge = null;' wewnątrz instrukcja 'else' nie będzie działać? Wypróbowałem to i jeśli raz się zaloguję z opcją "Zapamiętaj mnie" ustawioną na wartość true, wszystkie kolejne logowania będą również miały trwałe ustawienia plików cookie, nawet jeśli "Zapamiętaj mnie" jest wyłączone. – ragulka

+0

Właśnie zdałem sobie sprawę, że powinienem był użyć 'req.session.cookie.expires = false' zamiast tego, opublikuję alternatywną odpowiedź na to pytanie. – ragulka

2

Chociaż zdecydowanie chciałbym zobaczyć te funkcje w pliku passport.js, nie ma ich jeszcze.

Stworzyłem prosty generator losowych żetonów do użycia z funkcją passport.js serilizeUser() i zmodyfikowałem odpowiedź Justena tylko na moje potrzeby. Zasadniczo jedyną różnicą jest to, że jeśli opcja "zapamiętaj" nie jest ustawiona, sesja będzie trwać tak długo, jak długo przeglądarka jest otwarta.

To jest mój serializer z generatorem żetonów dostępu swobodnego. Używam Mongodb i Mongoose, ale implementacja powinna całkiem dobrze tłumaczyć się na inne systemy.

Zasadniczo otrzymuję czas i dołączam do niego losowy 16-znakowy ciąg znaków. Następnie w funkcji serializeUser() sprawdzam, czy żaden inny użytkownik nie ma tego samego tokena (token powinien być unikalny!).

User.methods.generateRandomToken = function() { 
    var user = this, 
     chars = "_!abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", 
     token = new Date().getTime() + '_'; 
    for (var x = 0; x < 16; x++) { 
    var i = Math.floor(Math.random() * 62); 
    token += chars.charAt(i); 
    } 
    return token; 
}; 

Oto serializer:

passport.serializeUser(function (user, done) { 

    var createAccessToken = function() { 
    var token = user.generateRandomToken(); 
    app.User.findOne({ accessToken: token }, function (err, existingUser) { 
     if (err) return done(err); 
     if (existingUser) 
     createAccessToken(); // Run the function again - the token has to be unique! 
     else { 
     user.set('accessToken', token); 
     user.save(function (err) { 
      if (err) return done(err); 
      return done(null, user.get('accessToken')); 
     }) 
     } 
    }); 
    }; 

    if (user._id) { 
    createAccessToken(); 
    } 
}); 

... i tutaj jest moja wersja oprogramowania pośredniczącego, który zajmuje się "Remember Me" funkcjonalność. Raczej wolałbym, żeby to było częścią funkcji serializeUser lub core passport.js.

app.use(express.session({ secret: 'secret_key' })); 
app.use(function (req, res, next) { 
    if (req.method == 'POST' && req.url == '/login') { 
     if (req.body.remember) { 
     req.session.cookie.maxAge = 30*24*60*60*1000; // Rememeber 'me' for 30 days 
     } else { 
     req.session.cookie.expires = false; 
     } 
    } 
    next(); 
}); 
app.use(passport.initialize()); 
app.use(passport.session()); 

Mam nadzieję, że jakoś to pomoże. Zajęło mi to kilka godzin, a ja nie jestem do końca pewien, czy to jest najlepszy sposób, ale na razie działa to dla mnie.

+0

Wiem, że to jest naprawdę stare, ale w jaki sposób pomocne jest tutaj oprogramowanie pośrednie sesji? Czy nie możemy tego po prostu pominąć? –

Powiązane problemy