È già noto che le password sono intrinsecamente deboli in natura. Quindi chiedere agli utenti finali di creare password sicure per ogni applicazione che usano semplicemente peggiora le cose.
Una facile soluzione è consentire agli utenti di autenticarsi tramite i propri account social esistenti come Facebook, Twitter, Google, ecc. In questo articolo, faremo proprio questo e aggiungeremo questa funzionalità di accesso social all'applicazione campione Node sviluppata nella prima parte di questa serie di autenticazione, in modo che saremo in grado di autenticarci tramite i nostri account Facebook e Twitter utilizzando il middleware Passport.
Se non hai verificato l'articolo precedente, ti consiglio di seguirlo, poiché svilupperemo le basi gettate da quell'articolo e aggiungendo nuove strategie, percorsi e viste.
Per chi non lo sapesse, l'accesso social è un tipo di Single Sign-on che utilizza le informazioni esistenti da siti di social network come Facebook, Twitter, ecc., Dove normalmente ci si aspetta che gli utenti abbiano già creato degli account.
L'accesso social si basa in gran parte su uno schema di autenticazione come OAuth 2.0. Per ulteriori informazioni sui diversi flussi di accesso supportati da OAuth, leggi questo articolo. Scegliamo Passport per gestire i social login per noi, in quanto fornisce diversi moduli per una varietà di provider OAuth, che si tratti di Facebook, Twitter, Google, GitHub, ecc. In questo articolo utilizzeremo i moduli passport-facebook e passport-twitter per fornire funzionalità di accesso tramite account Facebook o Twitter esistenti.
Per abilitare l'autenticazione di Facebook, dobbiamo prima creare un'app per Facebook utilizzando il Portale per gli sviluppatori di Facebook. Annota l'ID App e il Segreto App e specifica l'URL di richiamata andando a impostazioni e specificando il indirizzo del sito nel Sito web sezione per l'applicazione. Assicurati inoltre di inserire un indirizzo email valido per contatto email campo. È necessario essere in grado di rendere questa app pubblica e accessibile al pubblico.
Quindi, vai al Stato e revisione sezione e ruotare il cursore su sì per rendere pubblica l'app. Creiamo un file di configurazione, fb.js, per conservare queste informazioni di configurazione che saranno necessarie per connettersi a Facebook.
// Impostazioni app facebook - fb.js module.exports = 'appID': '',' appSecret ':' ',' callbackUrl ':' http: // localhost: 3000 / login / facebook / callback '
Tornando alla nostra applicazione Node, ora definiamo una Strategia Passport per l'autenticazione con Facebook usando il FacebookStrategy modulo, utilizzando le impostazioni di cui sopra per recuperare il profilo Facebook dell'utente e visualizzare i dettagli nella vista.
passport.use ('facebook', nuova FacebookStrategy (clientID: fbConfig.appID, clientSecret: fbConfig.appSecret, callbackURL: fbConfig.callbackUrl, // facebook invierà i token e la funzione profilo (access_token, refresh_token, profile, done ) // process asynchrono.nextTick (function () // trova l'utente nel database in base al loro ID facebook User.findOne ('id': profile.id, function (err, user) // if c'è un errore, si ferma tutto e si restituisce quel // // errore di connessione al database se (err) return done (err); // se l'utente viene trovato, quindi loggali if (user) return done (null , utente); // utente trovato, restituisce l'utente else // se non c'è nessun utente trovato con quell'ID facebook, creali var newUser = new User (); // imposta tutte le informazioni di Facebook nel nostro modello utente newUser.fb.id = profile.id; // imposta gli utenti facebook id newUser.fb.access_token = access_token; // salveremo il token che facebook fornisce all'utente newUser.fb.firstName = profile.n ame.givenName; newUser.fb.lastName = profile.name.familyName; // guarda il profilo utente del passaporto per vedere come vengono restituiti i nomi newUser.fb.email = profile.emails [0] .value; // facebook può restituire più e-mail in modo che prendiamo il primo // salva il nostro utente nel database newUser.save (function (err) if (err) throw err; // se ha successo, restituisce il nuovo user return fatto ( null, newUser);); ); ); ));
Ora dobbiamo aggiungere alcune rotte per abilitare il login con Facebook e per gestire la richiamata dopo che l'utente ha autorizzato l'applicazione a usare il suo account Facebook.
// percorso per l'autenticazione Facebook e login // diversi ambiti durante l'accesso a router.get ('/ login / facebook', passport.authenticate ('facebook', scope: 'email')); // gestisce la richiamata dopo che Facebook ha autenticato l'utente router.get ('/ login / facebook / callback', passport.authenticate ('facebook', successRedirect: '/ home', failureRedirect: '/'));
La pagina di accesso per la nostra applicazione demo ha il seguente aspetto:
Quando si fa clic sul Fai il login con facebook pulsante, cercherà di autenticare con Facebook. Se hai già effettuato l'accesso a Facebook, verrà mostrata la finestra di dialogo in basso per chiedere il tuo permesso, altrimenti ti chiederà di accedere a Facebook e quindi di mostrare questa finestra di dialogo.
Se si consente all'app di ricevere il proprio profilo pubblico e l'indirizzo e-mail, verrà richiamata la funzione di callback registrata con i dettagli dell'utente. Possiamo salvarli per riferimento futuro o visualizzarli o semplicemente scegliere di ignorarli, a seconda di cosa vuoi fare con le informazioni. Sentiti libero di andare avanti nel tempo e controlla l'intero codice in questo repository git.
È opportuno notare che, a parte le informazioni di base fornite da questa app dimostrativa, è possibile utilizzare lo stesso meccanismo di autenticazione per estrarre più informazioni utili sull'utente, come il suo elenco di amici, utilizzando l'ambito appropriato e utilizzando le API di Facebook con il token di accesso ricevuto con il profilo utente.
Un modulo di autenticazione simile deve essere cablato per gestire l'autenticazione tramite Twitter e chip Passport per aiutare con il suo modulo passport-twitter.
In primo luogo, è necessario creare una nuova app di Twitter utilizzando l'interfaccia di gestione delle applicazioni. Una cosa da notare qui è che mentre si specifica l'URL di callback, Twitter non sembra funzionare bene con esso se "localhost" è dato nel campo dell'URL di callback. Per superare questa limitazione durante lo sviluppo, è possibile utilizzare l'indirizzo di loopback speciale o "127.0.0.1" al posto di "localhost". Dopo aver creato l'app, annotare la seguente chiave API e informazioni segrete in un file di configurazione come segue:
// Impostazioni dell'app twitter - twitter.js module.exports = 'apikey': '',' apisecret ':' ',' callbackUrl ':' http://127.0.0.1:3000/login/twitter/callback '
La strategia di accesso per Twitter è un'istanza di TwitterStrategy
e sembra questo:
passport.use ('twitter', nuova TwitterStrategy (consumerKey: twitterConfig.apikey, consumerSecret: twitterConfig.apisecret, callbackURL: twitterConfig.callbackURL, function (token, tokenSecret, profile, done) // crea il codice asincrono // User.findOne non sparerà finché non avremo tutti i nostri dati da Twitter process.nextTick (function () User.findOne ('twitter.id': profile.id, function (err, user) // if c'è un errore, si interrompe tutto e si restituisce quel // // errore di connessione al database se (err) return done (err); // se l'utente viene trovato, loggatelo if (user) return done (null, utente); // utente trovato, restituisce tale utente else // se non c'è utente, creali var newUser = new User (); // imposta tutti i dati utente di cui abbiamo bisogno newUser.twitter.id = profilo .id; newUser.twitter.token = token; newUser.twitter.username = profile.username; newUser.twitter.displayName = profile.displayName; newUser.twitter.lastStatus = profile._json.status.text; // salva il nostro utente nel database newUser.save (function (err) if (err) gira err; return done (null, newUser); ); ); ); ));
// percorso per l'autenticazione e l'accesso a Twitter // diversi ambiti durante l'accesso a router.get ('/ login / twitter', passport.authenticate ('twitter')); // gestisce la richiamata dopo che Facebook ha autenticato l'utente router.get ('/ login / twitter / callback', passport.authenticate ('twitter', successRedirect: '/ twitter', failureRedirect: '/')); / * OTTENERE la pagina di visualizzazione di Twitter * / router.get ('/ twitter', isAuthenticated, function (req, res) res.render ('twitter', user: req.user););
Ora per testare questo, assicurati di usare http://127.0.0.1:
invece di usare http: // localhost
:
. Come abbiamo già detto sopra, sembra esserci un problema durante lo scambio di token con Twitter con "localhost" come nome host. Facendo clic su Accedi con Twitter pulsante, come previsto, richiede il consenso dell'utente per consentire a questa applicazione di utilizzare Twitter.
Quando si consente all'applicazione di accedere al proprio account Twitter e alle informazioni limitate, viene richiamato il gestore di richiamata registrato nella strategia di accesso, che viene quindi utilizzato per archiviare questi dettagli in un database di back-end
E il gioco è fatto !! Abbiamo aggiunto con successo gli accessi a Facebook e Twitter alla nostra applicazione di esempio senza scrivere molto codice e gestire le complessità implicate nel meccanismo di autenticazione lasciando che Passport faccia il lavoro pesante. Strategie di accesso simili possono essere scritte per una varietà di provider supportati da Passport. Il codice per l'intera applicazione può essere trovato in questo repository git. Sentiti libero di estenderlo e usarlo nei tuoi progetti.