< 8 mins read

Login social con Laravel + React Native

Mónica
Senior Mobile Developer

La gran mayoría de las aplicaciones requieren en algún punto que los usuarios se registren y creen una cuenta para tener una experiencia más personalizada. El problema es que cada vez acabamos con más cuentas, hay que rellenar formularios y posteriormente recordar qué contraseña se utilizó en cada aplicación. Una manera de simplificar este proceso es utilizar el login social, consumir de terceros conocidos como Facebook, Google, Twitter, Linkedin, etc. la autenticación de usuario para poder darse de alta y acceder a nuestra aplicación.

En este post veremos un ejemplo de cómo integrar el login social de Facebook utilizando un backend en Laravel y una aplicación móvil desarrollada con React Native.

Facebook

Los primero que haremos será crear una cuenta de desarrollador en facebook. Posteriormente accederemos a la sección «Mis aplicaciones«, y crearemos una nueva aplicación. En el primer paso tenemos que seleccionar el tipo de aplicación y en este caso cómo solo accederemos a datos públicos del perfil del usuario (email y nombre) seleccionaremos el tipo Ninguno.

Seleccionar tipo de aplicación en facebook
Consola de desarrollador de facebook

Completamos el resto de datos que nos piden como nombre y email, y una vez completado el proceso nos aparece una pantalla para añadir productos a la aplicación y seleccionamos únicamente el Inicio de sesión con Facebook.

Seleccionar productos facebook
Añadimos producto a nuestra app de facebook

Luego en Configuración > Información básica o en Inicio de sesión con Facebook > Guía de inicio rápido podremos configurar los datos de las apps como el identificador del paquete, pero más adelante veremos cómo hacer todas estas configuraciones con React Native.

Los parámetros que necesitamos para los siguientes pasos son el identificador de la aplicación y la clave secreta de la aplicación, que aparecen en Configuración > Información básica:

Claves app de facebook

Una vez completado estas datos vamos a ver el código de las distintas partes de nuestro software.

App React Native

En la aplicación móvil utilizamos el framework de React Native, nos permite crear aplicaciones nativas utilizando javascript como lenguaje de programación, soporta tanto el sistema operativo Android como para iOS.

Suponemos que ya tenemos una base de la aplicación con pantallas de login y registro, a las que añadiremos la funcionalidad de login social.

Para implementar el login social en nuestra app vamos a hacer uso de la siguiente librería React Native FBSDK Next que nos permite integrar nuestra app con facebook.

yarn add react-native-fbsdk-next

o

npm install --save react-native-fbsdk-next

Posteriormente es necesario instalar los pods para iOS

cd ios/ && pod install

Seguimos la guía para configurar la librería y las claves de Facebook en nuestra app. Resumimos los siguientes pasos:

Android

Añadimos en android/app/src/main/res/values/strings.xml los identificadores que hemos obtenido anteriormente en el panel de facebook:

<string name="facebook_app_id">xxxxxxxxxxxxxxxx</string>
<string name="facebook_client_token">xxxxxxxxxxxxxxxxxxxxxxxxxx</string>

Posteriormente añadimos en android/app/src/main/AndroidManifest.xml :

<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>
<meta-data android:name="com.facebook.sdk.ClientToken" android:value="@string/facebook_client_token"/>

iOS

Añadir en AppDelegate.m  el código resaltado en negrita:

#import <FBSDKCoreKit/FBSDKCoreKit.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  
  [FBSDKApplicationDelegate.sharedInstance initializeSDK];
  [[FBSDKApplicationDelegate sharedInstance] application:application
                           didFinishLaunchingWithOptions:launchOptions];
  return YES;
}


- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
            options:(nonnull NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options
{
  [[FBSDKApplicationDelegate sharedInstance] application:application
                                                 openURL:url
                                                 options:options];
  return YES;
}

Añadir en el archivo Info.plist dentro de las etiquetas <dict> … </dict> modificando los valores resaltados por los correspondientes de nuestra aplicación creada en facebook:

<key>CFBundleURLTypes</key>
<array>
  <dict>
  <key>CFBundleURLSchemes</key>
  <array>
    <string>fbAPP-ID</string>
  </array>
  </dict>
</array>
<key>FacebookAppID</key>
<string>APP-ID</string>
<key>FacebookClientToken</key>
<string>CLIENT-TOKEN</string>
<key>FacebookDisplayName</key>
<string>APP-NAME</string>

Donde los parámetros serían:

  • Reemplazar APP-ID por el identificador de la aplicación.
  • Reemplaza CLIENT-TOKEN por el valor de la clave secreta de la aplicación.
  • Reemplazar APP-NAME por el nombre de la aplicación.

y también habría que añadir dentro <dict> ... </dict>:

<key>LSApplicationQueriesSchemes</key>
<array>
  <string>fbapi</string>
  <string>fbapi20130214</string>
  <string>fbapi20130410</string>
  <string>fbapi20130702</string>
  <string>fbapi20131010</string>
  <string>fbapi20131219</string>
  <string>fbapi20140410</string>
  <string>fbapi20140116</string>
  <string>fbapi20150313</string>
  <string>fbapi20150629</string>
  <string>fbapi20160328</string>
  <string>fbauth</string>
  <string>fb-messenger-share-api</string>
  <string>fbauth2</string>
  <string>fbshareextension</string>
</array>

Javascript

Una vez tenemos configurado nuestras claves vamos a realizar la implementación en nuestra pantalla de Login 

La librería nos ofrece un botón ya diseñado con toda la funcionalidad integrada, que se utilizaría así:

import { LoginButton, AccessToken } from 'react-native-fbsdk-next';

...

<View>
    <LoginButton
        onLoginFinished={
            (error, result) => {
                if (error) {
                    console.log("login has error: " + result.error);
                } else if (result.isCancelled) {
                    console.log("login is cancelled.");
                } else {
                    AccessToken.getCurrentAccessToken().then(
                        (data) => {
                            console.log(data.accessToken.toString())
                        }
                    )
                }
            }
        }
        onLogoutFinished={() => console.log("logout")}/>
</View>

En nuestro caso vamos a crear nuestro propio botón que se integre con el diseño general de la aplicación.

<TouchableOpacity style={styles.btnBackground} onPress={() => requestFacebookLogin()}>
    <Text style={styles.btnText}>Iniciar sesión con Facebook</Text>
</TouchableOpacity>

El botón realiza la llamada a la librería y nos abrirá una pantalla nueva para introducir las credenciales de facebook o si tenemos la aplicación de facebook instalada en nuestro dispositivo se abrirá para que demos permiso a la aplicación para utilizar la autenticación y utilizar nuestros datos de perfil. Para esta aplicación solo necesitamos nombre y email.

const requestFacebookLogin = () => {
        LoginManager.logInWithPermissions(['public_profile', 'email']).then(
            function (result) {
                if (result.isCancelled) {
                    console.log('Login cancelled');
                } else {
                    console.log('Login success with permissions: ' + result.grantedPermissions.toString());

                    AccessToken.getCurrentAccessToken().then((data) => {
                        console.log('FbAccessToken', data.accessToken.toString());
                        sendSocialLogin('facebook', data.accessToken.toString());
                    });
                }
            },
            function (error) {
                console.log('Login fail with error: ' + error);
            },
        );
    };

Una vez que el usuario ha introducido sus credenciales y autorizado el login nos devuelve un resultado correcto en el callback y también nos dará un AccessToken que utilizaremos para enviar a nuestro backend.

Backend Laravel

En el backend utilizamos Laravel un framework de código abierto para desarrollo aplicaciones y servicios web con PHP.

Para utilizaremos la librería Laravel Socialite, permite la autenticación con distintos proveedores de OAuth. Actualmente soporta Facebook, Twitter, LinkedIn, Google, GitHub, GitLab y Bitbucket.

Lo primero que tendremos que hacer es instalar este paquete con composer.

composer require laravel/socialite

Posteriormente en el archivo de configuración deberemos poner las credenciales para el proveedor que hemos configurado. Una buena práctica es configurar estas claves como variables de entorno.

En el archivo .env configuramos nuestras claves:

FACEBOOK_CLIENT_ID=
FACEBOOK_CLIENT_SECRET=

En config/services.php:

'facebook' => [
        'client_id' => env('FACEBOOK_CLIENT_ID'),
        'client_secret' => env('FACEBOOK_CLIENT_SECRET'),
        'redirect' => '/facebook/callback-url',
],

Tenemos que crear una migración de la base de datos para agregar los datos nuevos que obtenemos del login social a la tabla de usuarios. Serían necesarias dos columnas provider_name donde guardaremos el nombre del proveedor, en este caso solo tenemos Facebook pero en un futuro podríamos agregar otros y en provider_id almacenaremos el token del usuario

Una vez tenemos estos nuevos campos creamos el endpoint para que el usuario nos envie el accestoken desde la app.

public function socialLogin(Request $request)
    {
        $provider = $request->get('provider_name');
        $access_token = $request->get('access_token');

        $providerUser = Socialite::driver($provider)->userFromToken($access_token);

        $user = User::where('provider_name', $provider)->where('provider_id', $providerUser->id)->first();

        if ($user == null) {
            $email = $providerUser->getEmail();
            $user = User::where('email', $email)->first();

            if ($user) {
                $user->provider_name = $provider;
                $user->provider_id = $providerUser->id;
                $user->save();
            } else {
                $user = User::create([
                    'name' => $providerUser->getName(),
                    'email' =>  $email,
                    'password' => Hash::make($email),
                    'provider_name' => $provider,
                    'provider_id' => $providerUser->id,
                ]);
            }
        }

        if ($user->tokens()) {
            $user->tokens()->delete();
        }

        return [
            "token" => $user->createToken($user->id)->plainTextToken,
            "user" => $user,
        ];
    }

En este endpoint obtenemos los datos del usuario del proveedor y luego comprobamos si ese usuario ya está registrado en nuestro sistema, si no está crearemos una nueva cuenta y si está registrado renovaremos los tokens para nuestra api.

Volvemos a facebook para dar de alta nuestras aplicaciones de iOS y Android en facebook

Como último paso una vez tengamos todo funcionando, antes de subir las actualizaciones de las aplicaciones a las respectivas store (AppStore y Google Play), hay que pasar la aplicación de facebook a modo productivo.

Contacto

Hola!

¿Quieres contarnos tu proyecto? ¡Escríbenos! Todo nuestro equipo teletrabaja el 100% del tiempo.

Ponte en contacto