Autenticación en Flutter

Eduardo CQ
Comunidad Flutter
Published in
17 min readSep 11, 2019

--

Hola gente, les traigo una traducción más para la comunidad Flutter en español. Esta vez escrita por el autor Greg Perry y lo puedes encontrar aquí.

Iniciar sesión usando el paquete de librería Auth.

paquete de librería auth

La autenticación es una tarea común para las aplicaciónes moviles, haciendola una candidata ideal para una biblioteca de clase. Una biblioteca de clase ejecutaría la tarea de manera normalizada y estandarizada; lo que facilitaría la autenticación. Yo uso una librería de clase para mis propias aplicaciones el paquete Dart Auth. Usaré un código de ejemplo para demostrar este paquete. Este código de ejemplo puede ser visto en el paquete de Dart example tab. Seguiré con el tradicional “paso a paso” de la biblioteca de clases con capturas de pantalla “fáciles de leer”.

Irónicamente, es mejor leer este artículo de desarrollo movil en su computadora que en el teléfono. Además de que tú programas principalmente en tu computadora, y no en tu teléfono. Por ahora.

Empecemos.

Otras historias por Greg Perry

Antes de hacer algo

Antes de hacer algo, tienes que configurar Firebase. No voy a instruirte esto paso a paso, ya que está más allá del alcance de este artículo. Puedes hacer eso por tu propia cuenta.Sin embargo, haré algunas capturas de pantalla dando pistas de lo que necesitas hacer, en lo que probablemente verás en tu pantalla si intentas adelantarte y ejecutar este paquete de biblioteca.

Sin Gists!

Nota, la mayoría de las capturas de pantalla tendrán su correspondiente gist o Github en sus leyendas. Puedes ir a esas entradas para copiar y pegar fácilmente el ejemplo. Personalmente encuentro los gists pesado para la vista, y no me gusta usarlos en mis artículos. Sin embargo, si tú miras esas cosas feas. Tienes la opción de dar click sobre la leyenda de la captura de pantalla.

Otro punto que debo mencionar aquí. Tal como están las cosas, soy Android.

Originalmente soy un desarrollador de Android, no iOS, por lo que la siguiente sección se aplica más a los desarrolladores de Android. Te pido disculpas, gente de iOS. Por favor, para usted, ¿qué tal si nos saltamos esta parte y pasamos al resto del artículo?

Ahora, en cuanto al resto de ustedes, quizás abran este sitio web, Agregar Firebase a su proyecto, como un suplemento para ayudarte a configurar Firebase, ya que voy a describir esto brevemente. Bajo el directorio android, agregue las siguientes dos dependencias al archivo build.gradle.

build.gradle

Ahora es importante agregar también lo siguiente al final del segundo archivo build.gradle. Este archivo se encuentra en el directorio: android/app

build.gradle

¿Qué hay en el Gradle?

Podrías encontrar el siguiente error si lo intentas con la biblioteca clase. Parece que hay un requisito mínimo de versión, y deberá ir al directorio “wrapper” y actualizar su archivo gradle-wrapper.properties. Por ejemplo, cambie la entrada del archivo, gradle-4.4-all.zip a gradle-5.1.1-all.zip.

Consigue tú JSON aquí!

El siguiente error que puede encontrar implica un archivo json. A continuación se muestra un ejemplo del error, y se queja de que falta el archivo json. Necesitarás ir a Firebase(manteniendo el nombre del paquete de su aplicación de muestra en mente) y hacer un archivo de configuración google-services.json: Proyectos Firebase.

Necesitarás un SHA1

Junto con ese archivo de configuración, probablemente necesitarás conseguir el número SHA1 para tu aplicación. Vuelve a este sitio web para obtener eso, Autenticando a su cliente. Y entonces, después de todo eso, estás listo para ejecutar la app de muestra e ingresa a Firebase.

Ejecuta tu app!

Con Firebase todo configurado, sigue adelante y ejecuta la aplicación de muestra y mira lo que hace. Como regla, yo ejecuto esas cosas en Android Studio usando un emulador.

Ahí tienes. Cuando todo está listo y ejecutas la aplicación, serás recibido con los botones ‘registrarse’. Ahora, a diferencia de la mayoría de mis paquetes de biblioteca, este funciona sin nada más que dos complementos: firebase_auth y google_sign_in. Y entonces, si tienes una cuenta Google Gmail, tienes los medios para iniciar sesión en la aplicación usando esa cuenta. Por ejemplo, click en el botón “Google Sign In” como se presentó arriba, y la aplicación te pedirá que inicies sesión usando su cuenta Google.

Lo que sigue son las capturas de pantalla del proceso:

La última captura de pantalla de arriba es interesante porque la aplicación(usando el parámetro ‘scopes’ de la biblioteca de clase) ha solicitado acceso a los contactos del usuario. A pesar de hacer click en el botón ‘allow’ yo mismo tengo una respuesta 403(PERMISOS DENEGADOS), y entonces no se accede a ninguno de mis contactos. Sospecho, que uno tendría que ir a la consola de desarrollador y habilitar tales permisos, pero francamente no voy a hacer eso. Sabiendo que funcionó, es lo suficientemente bueno por ahora. La captura de pantalla de abajo representa la biblioteca de clase usando su parámetro ‘scopes’ solicitando acceso a la información de contacto del usuario tal como la información de correo.

clase SignInDemoState

Luego de iniciar sesión satisfactoriamente, tú puedes tocar en la pestaña ‘Results’ para ver algunas de las muchas propiedades de las que tiene acceso a través del objeto de autenticación.
Estas propiedades serán presentadas un poco más adelante.

¿Cómo funciona?

Es en la función, initState(), en la aplicación de ejemplo cuando se inteta ‘iniciar sesión’. Hay unas ocho funciones diferentes en esta biblioteca de clase usadas para iniciar sesión. Por ejemplo, en la captura de pantalla de abajo, la función signInsilently(), es usada para permitir al usuario iniciar sesión automáticamente a travez de la cuenta Google sin involucrar el usuario si ya lo has hecho en el pasado. Si eso es así, la aplicación iniciará sesión silenciosamente en el momento. El parámetro llamado, listen, se disparará cuando haya iniciado sesión correctamente con Google.

De nuevo, ves en la función init(), estoy solicitando acceso a los contactos del usuario. Sin embargo, observe el segundo parámetro llamado, listener, suministra una función anónima para ser disparada cuando el usuario inicia sesión exitosamente usando en cambio Firebase y no Google. Y entonces, con dos complementos diferentes, hay dos controladores de eventos diferentes involucrados. Uno llamado, listen y otro listener.

clase SignInDemo

Por último, en la captura de pantalla de arriba, como cualquier buena biblioteca de clase, se limpia después de sí mismo cuando la aplicación termina llamando a su función dispose(), en la propia función dispose() del objeto de estado.

Cuando haya iniciado sesión

Cuando el usuario inicia sesión exitosamente usando Google, de nuevo, esa función anónima asignada al parámetro llamado listen, es desencadenada. Ahí la variable loggedIn, es asignada a un valor boleano dependiendo de si la variable account, es nula o no. Vea arriba.

La variable account, por cierto es de tipo GoogleSignInAccount, y cuando se ha registrado exitosamente contiene la información de la cuenta Google del usuario. Note que arriba la función setState(), es llamada next. Esto causa que el objeto de estado build() sea llamado y consecuentemente la función _buildBody(), para ser ejecutada. Cómo puedes ver en el código de abajo, si la variable loggedIn, se establece a verdadero, entonces eso mostrará el nombre y la dirección de correo del usuario en pantalla.

clase SignInDemoState

Hay más de una manera con las bibliotecas de clase

Abajo, verás que he cambiado un poco las cosas. La función init() ha sido modificada, ahora proporcione los dos parámetros del controlador de eventos dejando que la función de inicio de sesión se llame sin ningún parámetro. Esto demuestra cómo la biblioteca de clase permite que se llame a signInSilently() en otra parte(en cualquier sitio que el desarrollador quiera) dejando la función init() en el initState() para iniciar.

clase SignInDemoState

Escucha! Hay dos

Mirando de nuevo a los dos parámetros llamados: listener y listen. La diferencia entre ellos son sus valores de parámetros. La función listen, es usada para iniciar sesión con Google y es pasado el parámetro de clase tipo GoogleSignInAccount. La función listener, es usada para iniciar sesión con Firebase y es pasado el parámetro de clase tipo FirebaseUser. Puedes ver esto abajo con una captura de pantalla de la clase Auth y su constructor llamado Auth.init().

clase Auth

Preparate, listo!

Para ser breve, el código que demuestra esta biblioteca de clases se presenta en un solo lugar — en la función initState() — pero no tiene que hacerse todo en la función initState() por supuesto. Suponga, por ejemplo que tienes una aplicación que establece el alcance de la autenticación en un lugar, y las opciones del evento ‘event handler’ en otro lugar, o (como verás luego) establecer oyentes de autenticación más de una vez en muchos lugares diferentes del código. Tienes la opción de hacer esto usando la biblioteca de clase setters.

Al principio, había Init

Vamos a comenzar el tutorial sobre la biblioteca de clase. Mira en el parámetro list abajo. ¿Qué ves? Ves lo mismo ‘llamados parámetros’ verías si estabas usando los complementos separadamente… solo aquí se combinan. Debido a que son llamados parámetros, todos son opcionales, pero una vez que esta función es llamada, tú sabes una cosa: ambas instancias se han creado esos complementos. Son creados y almacenados en la respectiva variable estática señalada abajo. Observe, la biblioteca de clase en sí está también almacenada en una variable estática _this, porque esta clase usa un constructor factory.

clase Auth

Dispose

La función dispose() está enumerada abajo, y va a ser llamada en la función dispose() correspondiente de un objeto State. En otras palabras, es llamada cuando su aplicación está terminando. Esta función limpia las cosas al cerrar sesión y borra de la memoria una serie de variables “pesadas” — que toma mucha memoria valiosa.

clase Auth

Lo que sigue es las dos suscripciones de Stream implementadas “capturar” cualquiera y todos los eventos de autenticación que ocurran cuándo inicie sesión o cierre sesión por ejemplo. Es entonces la función de biblioteca privada _init(), una llamada al constructor, el cual es llamada por el constructor factory , de hecho para iniciar los dos complementos a las variables estáticas, _fireBaseAuth y _googleSignIn. Puedes ver el complemento ‘Google’ inicializado justo ahí en la función mientras el complemento ‘Firebase’ está actualmente inicializado mas adelante en la función _initFirebase().

clase Auth

De hecho, la función _initFireBase() es el siguiente fragmento de código enumerado en la biblioteca de clase. Ahí el complemento Firebase esta inicializado y referenciado en la variable _fireBaseAuth. Observe que una referencia al complemento también está asignada a una instancia de variable _fbAuth, haciéndola pública, disponible a travez de un getter.

clase Auth

Iniciar un incendio

Cuando una instancia del complemento FirebaseAuth es creado, es asignado a la función oyente _listFireBaseListeners. La variable lista _fireBaseListeners, es entonces usada para almacenar una o más funciones que pueden ser despedidas si un ‘cambio de autenticación’ ocurre. Por ejemplo, cuando un usuario de tipo FirebaseUser inicia sesión y/o cierra sesión. Ahí está la función fireBaseListener y el setter listener, dando dos maneras de asignar cualquier número de ‘oyentes’ a la biblioteca de clase.

clase Auth

Escucha!

Lo que sigue a continuación es la función _initListen(), y cómo has visto arriba, es llamada en la función _init(). Cuatro parámetros son pasados dentro de esta función —que luego se pasan al ‘oyente’ de GoogleSignIn.

Observe, el primer parámetro listen, es pasado indirectamente al oyente. Primero es agregado a la variable lista _googleListeners, que es mas adelante procesada en la función _listGoogleListeners, luego usa el for loop para pasar por todos esos oyentes.

clase Auth

Escucha Google!

Lo siguiente, es la misma función que es ese primer parámetro anterior _listGoogleListeners. Lo ves, en efecto, procesa la variable Lista _googleListeners, revelando lo que uno podría ver cómo es una característica profunda de esta biblioteca de clases — de nuevo, puedes asignar ‘cualquier número’ de oyentes a esta biblioteca de clase. Hay un bucle for para llamar a cada uno a su vez.

Otro programador, por ejemplo trabajando en otra parte de su aplicación puede también necesitar desencadenar un evento cuando la ‘autenticación cambia’. Esta biblioteca de clases permite que se activen múltiples funciones para este evento en particular. Además abajo, ves la función add() siendo utilizada en el setter llamado listen. Está agregando a la variable Lista una función de tipo GoogleListener, para luego ser llamada en este evento. Finalmente, hay una función llamada removeListen(), para eliminar una función particular si es necesario.

clase Auth

Ya Existe

La función alreadyLoggedIn(), sirve para reducir la recreación innecesaria de objetos importantes. Si el usuario ya esta conectado, no hay necesidad de iniciar sesión de nuevo. Es usada en toda la biblioteca de clase con casi todas las funciones de autenticación. También es pública, por lo que los desarrolladores pueden usarla.

clase Auth

Anónimamente

La siguiente función te permite registrarte en Firebase anónimamente. Mientras lo hace, te permite proveer una función ‘oyente’ para disparar después de que inicies sesión correctamente. Observe, que con esta función y prácticamente todas las otras funciones de inicio de sesión hay una sentencia try..catch para ‘capturar’ cualquier error que pueda ocurrir. La excepción luego es almacenada en la variable ‘library-private’ _ex, usando la función _setError().

clase Auth

Solo para demostrar, las tres capturas de pantalla de abájo muestran lo que sucede cuando das click en el botón ‘Log in anonymously’.

Por Correo Electrónico

La siguiente función le permitirá a uno iniciar sesión en Firebase usando su correo electrónico y contraseña. Hay algo de preparación involucrada aquí. Tienes que ir a tu consola Firebase y permitir contraseñas para ser usada para autenticación. Esto se detalla más adelante en el sitio web de Firebase.

Autentica con Firebase mediante cuentas basadas en contraseña en Android

Autentica con Firebase mediante cuentas basadas en contraseña en iOS

Como un aparte, tenga en cuenta que estoy usando los mismos nombres para las funciones como esas usadas por los complementos. Quiero hacer esta biblioteca de clase reconocible para desarrolladores. Si ellos ya saben cómo usar los complementos, sabrán cómo usar esta biblioteca de clase.

clase Auth

Buscar

Si su aplicación requiere que proporciones una lista de los proveedores, su usuario ha iniciado sesión, hay una función para eso: fetchProvidersForEmail(). ¿Por qué? ¿Cómo debería saber? Es su aplicación. El complemento proporciona tal función y también lo hace la biblioteca de clase. Lo que sigue entonces es un medio para ‘restablecer’ su contraseña. Eso es, si has iniciado sesión en Firebase con un correo electrónico y una contraseña, signInWithEmailAndPassword().

clase Auth
clase Auth

A continuación hay una demostración intentando iniciar sesión con un correo electrónico y una contraseña. Obviamente, todavía no realicé los pasos de preparación en este caso.

El código ejemplo mostrado abajo destaca el código involucrado en visualizar el mensaje de error. Demostrando cómo puedes, por supuesto, realizar operaciones asíncronas usando la biblioteca de clase.

clase SignInDemoState y _buildBody()

Sus Credenciales

La clase tipo AuthCredential, es usada por algunos sistemas (Google para uno) para obtener más información de autenticación del usuario conectado. De hecho, más adelante en esta biblioteca de clase, es usada para obtener tal información cuando inicia sesión usando Facebook. Tienes acceso a esta función de abajo también si quieres.

clase Auth

Inicio de sesión personalizado

Esta función es usada cuando tienes que ‘actualizar el inicio de sesión’. Iniciar sesión en Firebase solo dura una cierta cantidad de tiempo dependiendo (una hora me dijeron). Esta publicación ofrecerá una idea, firebase signInWithCustomToken broken

clase Auth

Como la documentación oficial establece la siguiente función de abajo, “Establece el código de idioma orientado al usuario para las operaciones de autenticación que se pueden internacionalizar, como [sendEmailVerification]. Este código de idioma debe seguir las convenciones definidas por el IETF en BCP47”

clase Auth

Desde Firebase

La siguiente función _setUserFromFirebase, es llamada solamente cada vez que se inicia sesión en Firebase y no en Google. Con esto, el parámetro es de tipo FirebaseUser. La información del perfil de usuario se asigna a las muchas variables estáticas a las que puedes accesar fácilmente con los ‘getters’ correspondientes de la biblioteca de clases.

clase Auth

Iniciar sesión en Firebase con Google

La siguiente función te permite iniciar sesión en Firebase usando Google. Inicia sesión en Google y luego inicia sesión en Firebase usando la credencial de Google suministrada.

Para eso está la función _setFireBaseWithGoogle().Se encontrará más abajo en el código. Toma la información recuperada del inicio de sesión de ‘Google’ y la usa para iniciar sesión en Firebase también.

clase Auth

Silenciosamente

Esta función iniciará sesión en el usuario, si ha iniciado sesión anteriormente. Regístrese en Google eso es, y luego inicia sesión en Firebase usando los credenciales de Google.

Error interno

Al escribir esto, noté un ‘error interno’ que estaba ocurriendo en el complemento la primera vez que inicia sesión en Google. Yo simplemente tengo el intento de biblioteca de clases nuevamente (en la declaración catch), y se inició sesión correctamente. Hay algo que me estoy perdiendo aquí … tal vez alguien pueda contribuir y ayudar.

clase Auth

Iniciar sesión

La siguiente función es usada para que el usuario inicie sesión manualmente con su cuenta Google. Uso esta función mucho, y es esta función cuando haces clic en el botón ‘iniciar sesión’ en el ejemplo presentado al comienzo de este artículo.

clase Auth

Usuario de Google

Esta siguiente función, toma la información en cuenta de un inicio de sesión exitoso en Google en forma de un objeto de clase GoogleSignInAccount. Esto es entonces pasado a esta función y suministra dos valores token, para luego iniciar sesión en Firebase. A las muchas variables estáticas de la biblioteca de clase, nuevamente, entonces son asignadas a la ‘información de perfil del usuario’ fácilmente accesible por sus correspondientes setters.

clase Auth

Es información auténtica

Una vez más, una vez que él usuario inicia sesión, tiene acceso a un poco de la información del usuario. La biblioteca de clases proporciona dicho acceso con el uso de una serie de getters demostrados en la aplicación de ejemplo en la pestaña “Resultados”.

Widget _authResults

Facebook

Puedes ver que hay un pequeño segmento de código listado abajo usando la función FlutterOAuth(). Esta luego llama a la función signInWithCredential(), encontrada anteriormente.

clase Auth

Twitter

En este momento, esta biblioteca de clase no inicia sesión usando Twitter. Hay un complemento para eso: flutter_twitter_login. Sin embargo por ahora, te invito a que leas Flutter+Firebase — Autenticación con Twitter por Etimbuk. Él presenta este complemento, y es este complemento el que suministra dos tokens que a su vez, pasaría a la función de abajo:

clase Auth

Desconectar

Cerrar sesión es cerrar sesión en el servidor de Google y en el servidor de Firebase. Volviendo a la aplicación, es posible firmar ‘en silencio’ sin que el usuario inicie sesión manualmente nuevamente. Sin embargo, si cierras sesión y luego se desconecta, el usuario de nuevo tendrá que iniciar sesión manualmente.

clase Auth

Cerrar sesión

Es buena práctica cerrar sesión explícitamente cuando la aplicación está terminando. La función dispose() llama a la función signOut() listada abajo. Ves simplemente que llama a la función signOut del complemento, respectivamente. Tenga en cuenta que no se desconecta, pero la función que sigue sí.

clase Auth

Conectado o no

Las siguientes dos funciones prueban si actualmente está ‘conectado’. De nuevo la función init() es invocada en las dos últimas funciones para asegurarse, en este caso, la variable _googleSignIn no es nula.

clase Auth

A continuación, es la función interna para registrar cualquier error que la biblioteca de clase pueda encontrar. Ahí está la función getError(), para recuperar tales errores.

clase Auth
clase Auth

Información del setter

La biblioteca de clase termina nuevamente con varios getters que transmiten la información del perfil del usuario. Por supuesto, se actualizan en cualquiera de las funciones _setUserFromFirebase() o _setFireBaseUserFromGoogle().

clase Auth

Conclusión

Mucha redundancia en esta biblioteca de clase. Eso es lo que la hace una biblioteca de clase. Fea por dentro pero pulida por fuera. Solo unas pocas llamadas y ya terminaste de autenticar a los usuarios de tu aplicación. Esta biblioteca de clase es solo otra herramienta en el kit de herramientas para hacer la vida un poco más fácil cuando desarrollas aplicaciones móviles en Flutter — la mejor plataforma para el desarrollo móvil.

Leer algunas de mis arículos y traducciones recientes de artículos sobre Flutter.

Si este artículo te ayudo en algo incluso en una o dos cosas, aplauda tantas veces como pueda para mostrar su apoyo. 👏

Soy Eduardo Coto. Técnico de computadoras y desarrollador de aplicaciones Flutter.
Puedes encontrarme en GitHub
Sígueme en Twitter.

--

--