Advertisement
  1. Code
  2. Node.js

Identificación mediante redes sociales usando Passport para aplicaciones Node.js

Scroll to top
Read Time: 8 min

Spanish (Español) translation by Elías Nicolás (you can also view the original English article)

Es un hecho bien demostrado que las contraseñas son inherentemente débiles por naturaleza. De manera que pedir a los usuarios finales que creen contraseñas seguras para cada una de las aplicaciones que utilizan simplemente empeora esta cuestión.

Es una solución fácil permitir a los usuarios autenticarse mediante sus cuentas sociales existentes como Facebook, Twitter, Google, etc.. En este artículo, vamos a hacer justamente eso y agregar esta capacidad de acceso social a la aplicación Node de muestra desarrollada en la primera parte de esta serie sobre autenticación, de forma que seamos capaces de autenticarnos a través de nuestras cuentas de Facebook y Twitter utilizando el middleware Passport.

Si no has echado un vistazo al artículo anterior, te recomiendo que lo hagas, puesto que vamos a trabajar sobre la base establecida en dicho artículo y a añadirle nuevas estrategias, rutas y vistas.

Acceso social

Para los no-iniciados, el acceso social es un tipo de identificación única usando información existente de sitios de redes sociales como Facebook, Twitter, etc., donde se espera normalmente que los usuarios tengan ya cuentas creadas.

El acceso social se basa principalmente en un esquema de autenticación como OAuth 2.0. Para obtener más información sobre los diferentes flujos de inicio de sesión que soporta OAuth, lee este artículo. Elegimos Passport para manejar el acceso social por nosotros, ya que proporciona diferentes módulos para una variedad de proveedores de OAuth, ya sea Facebook, Twitter, Google, GitHub, etc.. En este artículo usaremos los módulos passport-facebook y passport-witter para proporcionar funcionalidad de inicio de sesión a través de las cuentas existentes de Facebook o Twitter.

Autenticación a través de Facebook

Para habilitar la autenticación a través de Facebook, primero tenemos que crear una Facebook App utilizando el Facebook Developer Portal. Anota el App ID (identificador de la aplicación) y el App Secret (secreto de la aplicación), y especifica la URL de callback yendo a Ajustes (Settings) y especificando la URL del sitio (Site URL) en la sección Website para la aplicación. También asegúrate de introducir una dirección válida de correo electrónico para el campo Contact Email (correo electrónico de contacto). Es un requisito para poder realizar esta aplicación pública y accesible por el público.

A continuación, vaya a la sección Estado y revisión y gire el control deslizante a para que la aplicación sea pública. Creamos un archivo de configuración, fb.js, para mantener esta información de configuración que será necesaria para conectarse a Facebook.

1
// facebook app settings - fb.js
2
module.exports = {
3
  'appID' : '<your_app_identifier>',
4
  'appSecret' : '<your_app_secret>',
5
  'callbackUrl' : 'https://localhost:3000/login/facebook/callback'
6
}

Estrategia de acceso al Facebook

De nuevo en nuestra aplicación de nodo, ahora definimos una Estrategia de Pasaporte para autenticar con Facebook usando el módulo FacebookStrategy, utilizando las configuraciones anteriores para obtener el perfil de Facebook del usuario y mostrar los detalles en la vista.

1
passport.use('facebook', new FacebookStrategy({
2
  clientID        : fbConfig.appID,
3
  clientSecret    : fbConfig.appSecret,
4
  callbackURL     : fbConfig.callbackUrl
5
},
6
7
  // facebook will send back the tokens and profile

8
  function(access_token, refresh_token, profile, done) {
9
  // asynchronous

10
	process.nextTick(function() {
11
    
12
	  // find the user in the database based on their facebook id

13
	  User.findOne({ 'id' : profile.id }, function(err, user) {
14
15
	    // if there is an error, stop everything and return that

16
	    // ie an error connecting to the database

17
	    if (err)
18
	      return done(err);
19
20
		  // if the user is found, then log them in

21
	      if (user) {
22
	        return done(null, user); // user found, return that user

23
	      } else {
24
	        // if there is no user found with that facebook id, create them

25
	        var newUser = new User();
26
27
			// set all of the facebook information in our user model

28
	        newUser.fb.id    = profile.id; // set the users facebook id	                

29
	        newUser.fb.access_token = access_token; // we will save the token that facebook provides to the user	                

30
	        newUser.fb.firstName  = profile.name.givenName;
31
	        newUser.fb.lastName = profile.name.familyName; // look at the passport user profile to see how names are returned

32
	        newUser.fb.email = profile.emails[0].value; // facebook can return multiple emails so we'll take the first

33
34
			// save our user to the database

35
	        newUser.save(function(err) {
36
	          if (err)
37
	            throw err;
38
39
	          // if successful, return the new user

40
	          return done(null, newUser);
41
	        });
42
	     } 
43
	  });
44
    });
45
}));

Configuración de rutas

Ahora necesitamos agregar ciertas rutas para permitir el inicio de sesión con Facebook y para manejar la devolución de llamada después de que el usuario haya autorizado la aplicación para usar su cuenta de Facebook.

1
// route for facebook authentication and login

2
// different scopes while logging in

3
router.get('/login/facebook', 
4
  passport.authenticate('facebook', { scope : 'email' }
5
));
6
7
// handle the callback after facebook has authenticated the user

8
router.get('/login/facebook/callback',
9
  passport.authenticate('facebook', {
10
    successRedirect : '/home',
11
	failureRedirect : '/'
12
  })
13
);

La página de inicio de sesión de nuestra aplicación de demostración se ve así:

Login With Facebook or TwitterLogin With Facebook or TwitterLogin With Facebook or Twitter

Al hacer clic en el botón Iniciar sesión con Facebook, intentará autenticarse con Facebook. Si ya has iniciado sesión en Facebook, mostrará el cuadro de diálogo siguiente pidiendo tu permiso, o bien te pedirá que inicies sesión en Facebook y luego muestres este diálogo.

Facebook Auth - Grant PermissionsFacebook Auth - Grant PermissionsFacebook Auth - Grant Permissions

Si permite que la aplicación reciba su perfil público y su dirección de correo electrónico, se llamará a nuestra función de devolución de llamada registrada con los detalles del usuario. Podemos guardarlos para futuras referencias o mostrarlos o simplemente optar por ignorarlos, dependiendo de lo que quiera hacer con la información. Siéntase libre de saltar adelante en el tiempo y echa un vistazo al código completo en este repo git.

Sería bueno tener en cuenta que, aparte de la información básica que ofrece esta aplicación de demostración, podría utilizar el mismo mecanismo de autenticación para extraer más información útil sobre el usuario, como su lista de amigos, utilizando el ámbito apropiado y utilizando las API de Facebook con el token de acceso recibido con el perfil de usuario.

Autenticación de Twitter

Un módulo de autenticación similar necesita estar cableado para gestionar la autenticación a través de Twitter y Passport chips para ayudar con su módulo passport-passport.

En primer lugar, es necesario crear una nueva aplicación de Twitter utilizando su interfaz de administración de aplicaciones. Una cosa a tener en cuenta aquí es que mientras se especifica la URL de devolución de llamada, Twitter no parece funcionar bien si se da "localhost" en el campo de URL de devolución de llamada. Para superar esta limitación durante el desarrollo, puede utilizar la dirección de bucle especial o "127.0.0.1" en lugar de "localhost". Después de crear la aplicación, anote la siguiente clave de la API y la información secreta en un archivo de configuración de la siguiente manera:

1
// twitter app settings - twitter.js

2
module.exports = {
3
    'apikey' : '<your_app_key>',
4
	'apisecret' : '<you_app_secret>',
5
	'callbackUrl' : 'http://127.0.0.1:3000/login/twitter/callback'
6
}

Estrategia de acceso de Twitter

La estrategia de inicio de sesión para Twitter es una instancia de TwitterStrategy y se ve así:

1
passport.use('twitter', new TwitterStrategy({
2
    consumerKey     : twitterConfig.apikey,
3
    consumerSecret  : twitterConfig.apisecret,
4
    callbackURL     : twitterConfig.callbackURL
5
  },
6
  function(token, tokenSecret, profile, done) {
7
    // make the code asynchronous

8
    // User.findOne won't fire until we have all our data back from Twitter

9
    process.nextTick(function() { 
10
11
	  User.findOne({ 'twitter.id' : profile.id }, 
12
        function(err, user) {
13
          // if there is an error, stop everything and return that

14
		  // ie an error connecting to the database

15
	      if (err)
16
	        return done(err);
17
18
			// if the user is found then log them in

19
	        if (user) {
20
	           return done(null, user); // user found, return that user

21
	        } else {
22
	           // if there is no user, create them

23
	           var newUser                 = new User();
24
25
			   // set all of the user data that we need

26
	           newUser.twitter.id          = profile.id;
27
	           newUser.twitter.token       = token;
28
	           newUser.twitter.username = profile.username;
29
	           newUser.twitter.displayName = profile.displayName;
30
	           newUser.twitter.lastStatus = profile._json.status.text;
31
32
			   // save our user into the database

33
	           newUser.save(function(err) {
34
	             if (err)
35
	               throw err;
36
	             return done(null, newUser);
37
	           });
38
	        }
39
	     });
40
	  });
41
    })
42
);

Configuración de rutas

1
// route for twitter authentication and login

2
// different scopes while logging in

3
router.get('/login/twitter',  
4
  passport.authenticate('twitter')
5
);
6
7
// handle the callback after facebook has authenticated the user

8
router.get('/login/twitter/callback',
9
  passport.authenticate('twitter', {
10
	successRedirect : '/twitter',
11
	failureRedirect : '/'
12
  })
13
);
14
15
/* GET Twitter View Page */
16
router.get('/twitter', isAuthenticated, function(req, res){
17
  res.render('twitter', { user: req.user });
18
});

Ahora para probar esto, asegúrese de usar http://127.0.0.1: <port> en lugar de usar http://localhost:<port>. Como ya hemos mencionado anteriormente, parece que hay un problema al intercambiar fichas con Twitter con "localhost" como nombre de host. Al hacer clic en el botón Iniciar sesión con Twitter, como se espera, pide el consentimiento del usuario para permitir que esta aplicación utilice Twitter.

Twitter Auth - Grant PermissionsTwitter Auth - Grant PermissionsTwitter Auth - Grant Permissions

Al permitir que la aplicación acceda a su cuenta de Twitter y la información limitada, se llama al manejador de devolución de llamada que está registrado en la estrategia de inicio de sesión, que se utiliza para almacenar estos detalles en una base de datos de fondo

Conclusión

¡¡Y ahí lo tienes!! Hemos añadido con éxito los inicios de sesión de Facebook y Twitter a nuestra aplicación de ejemplo sin escribir mucho código y manejar las complejidades involucradas con el mecanismo de autenticación permitiendo que Passport haga el trabajo pesado. Se pueden escribir estrategias de inicio de sesión similares para una variedad de proveedores que soporta Passport. El código para toda la aplicación se puede encontrar en este repositorio git. Siéntase libre de extenderlo y usarlo en sus propios proyectos.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.