Introducción
Esta guía es un complemento de Cómo configurar la autenticación de Firebase con una aplicación web React . En la introducción de esa guía, señalé que Firebase ofrece otros esquemas de autenticación más allá de la autenticación básica de correo electrónico/contraseña. Una de esas alternativas es la Autenticación sin contraseña .
La autenticación sin contraseña es una opción atractiva a la hora de crear aplicaciones. Simplifica la experiencia del usuario, ya que sus usuarios no necesitan recordar sus contraseñas y, por lo tanto, tampoco tienen que preocuparse por perderlas. También facilita la experiencia de desarrollo ya que no es necesario diseñar ninguna lógica de gestión o captura de contraseñas.
En esta guía, creará un flujo de trabajo simple de inicio de sesión/confirmación/perfil/cierre de sesión que implemente la autenticación sin contraseña de Firebase.
Antes de que empieces
Google establece varios límites de autenticación de Firebase. Si está utilizando el plan Spark gratuito, tenga en cuenta que estará limitado a 5 correos electrónicos con enlaces de inicio de sesión por día. Si bien el plan Spark puede ser suficiente para fines de prueba, deberá actualizar al plan Blaze de pago por uso para superar este límite.
Requisitos previos
A lo largo de esta guía, me referiré a la guía Cómo configurar la autenticación de Firebase con una aplicación web React como guía de requisitos previos y al proyecto asociado como proyecto de requisitos previos .
Para completar esta guía, necesitará tener:
- Completó la guía de requisitos previos, incluidos todos sus requisitos previos.
Paso 1: habilitar la autenticación sin contraseña con su proyecto Firebase
En la guía de requisitos previos, creó un nuevo proyecto de Firebase para la autenticación básica de correo electrónico/contraseña. Ahora, habilitará ese mismo proyecto para la autenticación sin contraseña. Inicie sesión en su cuenta de Firebase y haga clic en Ir a la consola .
Haga clic en su proyecto de autenticación que aparece en el panel de proyectos de Firebase. Esta guía utiliza el nombre del proyecto
my-auth-test
.Haga clic en autenticación en el menú del panel izquierdo.
Haga clic en la pestaña Método de inicio de sesión en la ventana principal.
Según su trabajo en la guía de requisitos previos, la tabla Proveedores de inicio de sesión ya debería mostrar Correo electrónico/Contraseña en la columna Proveedores con el estado Habilitado . Haga clic en el icono de lápiz para abrir el panel de configuración del proveedor de correo electrónico/contraseña .
Haga clic en el interruptor para habilitar el enlace de correo electrónico (inicio de sesión sin contraseña) .
Haga clic en Guardar .
Su proyecto de Firebase ahora está configurado para admitir la autenticación sin contraseña.
Paso 2: crear un nuevo proyecto de React e instalar paquetes
Paso 2a: crear un nuevo proyecto de React
Cree un nuevo proyecto de React usando el nombre de la aplicación que desee. Esta guía utiliza passwordless-auth
.
npx create-react-app passwordless-auth
Paso 2b: instalación de paquetes
Esta guía requiere la instalación de 3 paquetes de Node.js:
- Firebase : el SDK de Firebase.
- React Router DOM : para enrutamiento.
- Bootstrap : Para estilizar.
Instale cada uno de los tres paquetes anteriores a través de npm
:
npm install firebase
npm install react-router-dom
npm install bootstrap
Paso 3: copia firebase.js
del proyecto de requisitos previos
En el proyecto de requisitos previos, creó un archivo firebase.js
que utiliza los datos de configuración de su proyecto Firebase para crear una instancia del servicio Firebase Authentication. Su archivo firebase.js
debe tener la siguiente estructura con los valores de configuración de su proyecto Firebase:
import { initializeApp } from "firebase/app"; import { getAuth } from "firebase/auth"; const firebaseConfig = { apiKey: "AIzaSyDiUlY68W9Li_0EIkmdGdzD7nvqCT9kHnY", authDomain: "my-auth-test-fbd48.firebaseapp.com", projectId: "my-auth-test-fbd48", storageBucket: "my-auth-test-fbd48.appspot.com", messagingSenderId: "1078604952662", appId: "1:1078604952662:web:5d0b908439cfb5684ab7f7" } const app = initializeApp(firebaseConfig); const auth = getAuth(app); export { auth }
Copie firebase.js
a su nueva carpeta de proyecto de React.
Si necesita revisar la configuración de su proyecto de Firebase, haga clic en el ícono de ajustes junto a Descripción general del proyecto en el menú del panel izquierdo. La pestaña General ya debería estar seleccionada. Desplácese hacia abajo hasta la sección Sus aplicaciones que contiene el panel de aplicaciones web . La opción npm dentro del panel de aplicaciones web ya debería estar seleccionada. Los valores de configuración de su proyecto aparecerán en el bloque de código mostrado.
Paso 4: creación de la aplicación React
Paso 4a: descripción general de los componentes de la aplicación React
La aplicación React constará de 5 componentes: App
, Layout
, Login
, Confirm
y Profile
.
App
- El componente
App
define la estructura general de la aplicación, incluido el enrutamiento.
Layout
- El componente
Layout
especifica el marcado de la aplicación que permanece consistente en todas las rutas.
Login
- El punto de entrada del usuario a la aplicación es el formulario de inicio de sesión.
- Cuando un usuario intenta iniciar sesión a través de su dirección de correo electrónico, se envía un correo electrónico con un enlace de inicio de sesión a su dirección de correo electrónico.
Confirm
- El usuario es dirigido a la página
Confirm
cuando hace clic en un enlace de inicio de sesión. - La página solicita al usuario que confirme la dirección de correo electrónico utilizada cuando inició sesión.
Profile
- El usuario es dirigido a la página
Profile
después de confirmar su dirección de correo electrónico. - El usuario puede hacer clic en un botón de cierre de sesión en la página
Profile
para cerrar sesión en su cuenta.
El directorio src
final contendrá los siguientes archivos:
src |__ index.js |__ firebase.js // Copied from prerequisite project in Step 3. |__ App.js |__ Layout.jsx |__ Login.jsx |__ Confirm.jsx |__ Profile.jsx
Paso 4b: limpiar la plantilla del proyecto React y copiar archivos del proyecto de requisitos previos
- Puede eliminar los mismos archivos de la plantilla del proyecto React como se describe en el Paso 5b.1 de la guía de requisitos previos. Elimine los siguientes archivos de su proyecto React:
-
reportWebVitals.js
-
setupTests.js
-
logo.svg
-
index.css
-
App.css
-
App.test.js
Copie
index.js
del proyecto de requisitos previos a la carpeta de su nuevo proyecto. Esta guía utiliza el mismo archivo. Si necesita reconstruirindex.js
, consulte el Paso 5b.2 de la guía de requisitos previos o copie el bloque de código a continuación.Copie
Layout.jsx
del proyecto de requisitos previos a la carpeta de su nuevo proyecto. Esta guía utiliza el mismo archivo. Si necesita reconstruirLayout.jsx
, consulte el Paso 5d de la guía de requisitos previos o copie el bloque de código a continuación. Opcionalmente, puede actualizar el texto del proyecto en la etiqueta<p>
deLayout.jsx
paraReact With Firebase Passwordless Authentication
o cualquier título que prefiera.
Sus archivos index.js
y Layout.jsx
deben ser los siguientes:
// index.js import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './App'; import "bootstrap/dist/css/bootstrap.min.css"; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <App /> </React.StrictMode> );
// Layout.jsx import { Outlet } from "react-router-dom"; const Layout = () => { return( <div className = "container-fluid"> <div className = "row justify-content-center mt-3"> <div className = "col-md-4 text-center"> <p className = "lead">React With Firebase Passwordless Authentication</p> </div> <Outlet /> </div> </div> ) } export default Layout
Paso 4c: creación de App.js
El archivo App.js
es prácticamente el mismo que el del proyecto de requisitos previos, con cambios en solo dos líneas. Para facilitar la creación del archivo, copie App.js
del proyecto de requisitos previos a su nueva carpeta de proyecto.
Elimine la siguiente línea
import
del archivo y reemplácela como se muestra a continuación:
// Delete this line: import Signup from "./Signup";
// Replace it with: import Confirm from "./Confirm";
Elimine la siguiente
<Route>
del archivo y reemplácela como se muestra a continuación:
// Delete this line: <Route path = "/signup" element = { <Signup></Signup> } ></Route>
// Replace it with: <Route path = "/confirm" element = { <Confirm></Confirm> } ></Route>
Guarde
App.js
El archivo completo ahora debería ser el siguiente:
import Layout from "./Layout"; import Login from "./Login"; import Confirm from "./Confirm"; import Profile from "./Profile"; import { BrowserRouter, Routes, Route } from "react-router-dom"; const App = () => { return ( <BrowserRouter> <Routes> <Route path = "/" element = { <Layout></Layout> }> <Route index element = { <Login></Login> }></Route> <Route path = "/confirm" element = { <Confirm></Confirm> } ></Route> <Route path = "/profile" element = { <Profile></Profile> } ></Route> </Route> </Routes> </BrowserRouter> ) } export default App
Tenga en cuenta que el componente Login
vuelve a ser la ruta de inicio de la aplicación, como lo era con el proyecto de requisitos previos.
Paso 4d: creación de Login.jsx
En el caso de la autenticación sin contraseña, obviamente no es necesario incluir un campo de contraseña ni administrar el estado para ingresar la contraseña. Por lo tanto, el formulario de inicio de sesión solo necesita capturar la dirección de correo electrónico del usuario.
Cree un nuevo archivo
Login.jsx
en el directoriosrc
.Agregue el siguiente código:
import { useState } from "react"; import { auth } from "./firebase"; import { sendSignInLinkToEmail } from "firebase/auth"; const Login = () => { const [email, setEmail] = useState(""); const [notice, setNotice] = useState(""); const actionCodeSettings = { url: "http://localhost:3000/confirm", handleCodeInApp: true } const callSendSignInLinkToEmail = (e) => { e.preventDefault(); sendSignInLinkToEmail(auth, email, actionCodeSettings) .then(() => { setNotice("An email was sent to your email address. Click the link in the email to login."); }) .catch((error) => { setNotice("An error occurred when sending a login link to your email address: ", error.name); }) } return( <div className = "container"> <div className = "row justify-content-center"> <form className = "col-md-4 mt-3 pt-3 pb-3"> { "" !== notice && <div className = "alert alert-warning" role = "alert"> { notice } </div> } <div className = "form-floating mb-3"> <input type = "email" className = "form-control" id = "exampleInputEmail" placeholder = "[email protected]" value = { email } onChange = { (e) => setEmail(e.target.value) }></input> <label htmlFor = "exampleInputEmail" className = "form-label">Email address</label> </div> <div className = "d-grid"> <button type = "submit" className = "btn btn-primary pt-3 pb-3" onClick = {(e) => callSendSignInLinkToEmail(e)}>Submit</button> </div> </form> </div> </div> ) }
- Guarde
Login.jsx
.
Al capturar la dirección de correo electrónico del usuario, el formulario Login.jsx
envía un correo electrónico con un enlace de inicio de sesión a su dirección a través del método sendSignInLinkToEmail
de Firebase. Si tiene éxito, se notifica al usuario que se ha enviado el correo electrónico. Tenga en cuenta que el objeto actionCodeSettings
se pasa como parámetro al método sendSignInLinkToEmail
e incluye la URL a la que se dirigirá al usuario cuando haga clic en el enlace de inicio de sesión enviado por correo electrónico. En este caso, la URL se asigna a la ruta /confirm
especificada en App.js
Paso 4e: creación de Confirm.jsx
El método signInWithEmailLink
de Firebase se utiliza para iniciar sesión en un usuario que ha hecho clic en un enlace de inicio de sesión. Como verá en un momento, el método toma un parámetro email
y el valor del email
debe coincidir con la dirección de correo electrónico que el usuario utilizó al iniciar sesión a través del formulario de inicio de sesión. Confirm.jsx
presenta al usuario un formulario para confirmar su dirección de correo electrónico y posteriormente intenta iniciar sesión.
Cree un nuevo archivo
Confirm.jsx
en el directoriosrc
.Agregue el siguiente código:
import { useState } from "react"; import { auth } from "./firebase"; import { isSignInWithEmailLink, signInWithEmailLink } from "firebase/auth"; import { useNavigate } from "react-router-dom"; const Confirm = () => { const navigate = useNavigate(); const [email, setEmail] = useState(""); const [notice, setNotice] = useState(""); const callSignInWithEmailLink = (e) => { e.preventDefault(); if (isSignInWithEmailLink(auth, window.location.href)) { signInWithEmailLink(auth, email, window.location.href) .then(() => { navigate("/profile"); }) .catch((error) => { setNotice("An occurred during sign in: ", error.name); }) } } return( <div className = "container"> <div className = "row justify-content-center"> <form className = "col-md-4 mt-3 pt-3 pb-3"> { "" !== notice && <div className = "alert alert-warning" role = "alert"> { notice } </div> } <div className = "form-floating mb-3"> <input type = "email" className = "form-control" id = "exampleConfirmEmail" placeholder = "[email protected]" value = { email } onChange = { (e) => setEmail(e.target.value) }></input> <label htmlFor = "exampleConfirmEmail" className = "form-label">Please confirm your email address</label> </div> <div className = "d-grid"> <button type = "submit" className = "btn btn-primary pt-3 pb-3" onClick = {(e) => callSignInWithEmailLink(e)}>Confirm</button> </div> </form> </div> </div> ) } export default Confirm
- Guarde
Confirm.jsx
.
El método isSignInWithEmailLink
primero comprueba si el enlace de inicio de sesión que utiliza el usuario es válido. Si es así, se llama al método signInWithEmailLink
para iniciar sesión como usuario. Para reiterar, el valor email
pasado al método signInWithEmailLink
debe coincidir con la dirección de correo electrónico que el usuario utilizó con el formulario de inicio de sesión. Tenga en cuenta que si el usuario es un usuario nuevo (es decir, es la primera vez que inicia sesión), Firebase creará automáticamente el usuario en el almacén de autenticación de Firebase. Este es otro ejemplo de la experiencia simplificada que ofrece la autenticación sin contraseña: la creación de cuentas para nuevos usuarios se gestiona automáticamente.
Paso 4f: creación de Profile.jsx
El componente final que creará es Profile.jsx
. Los usuarios son dirigidos a este componente cuando inician sesión correctamente a través de Confirm.jsx
. La ruta da la bienvenida al usuario con su dirección de correo electrónico y proporciona un botón para cerrar sesión. Al cerrar sesión, el usuario regresa al componente Login
.
Cree un nuevo archivo
Profile.jsx
en el directoriosrc
.Agregue el siguiente código:
import { auth } from "./firebase"; import { signOut } from "firebase/auth"; import { useNavigate } from "react-router-dom"; const Profile = () => { const navigate = useNavigate(); const logoutUser = async (e) => { e.preventDefault(); await signOut(auth); navigate("/"); } return( <div className = "container"> <div className = "row justify-content-center"> <div className = "col-md-4 text-center"> <p>Welcome <em className = "text-decoration-underline">{ auth.currentUser.email }</em>. You are logged in!</p> <div className = "d-grid gap-2"> <button type = "submit" className = "btn btn-primary pt-3 pb-3" onClick = {(e) => logoutUser(e)}>Logout</button> </div> </div> </div> </div> ) } export default Profile
- Guardar
Profile.jsx
.
Paso 5: probar la aplicación
Inicie la aplicación React:
npm start
- Navegue hasta
locahost:3000
en su navegador si su navegador no se inicia automáticamente. Deberías ver el formularioLogin
.
Ingrese el correo electrónico que desea utilizar para iniciar sesión y haga clic en Enviar . Si el envío se realiza correctamente, se mostrará una notificación indicando que se envió un correo electrónico con un enlace de inicio de sesión a su dirección de correo electrónico.
- Inicie sesión en su cuenta de correo electrónico y busque el correo electrónico con el enlace de inicio de sesión de Firebase. Debe tener una línea de asunto similar a
Sign in to project-1078604952662
, donde la secuencia numérica de 13 dígitos representa elmessagingSenderId
de su proyecto de Firebase (consulte el Paso 3 de esta guía). En la sección Opcional a continuación, explicaré cómo puede modificar el nombre de su proyecto de Firebase para mostrar un nombre "fácil de usar" en los correos electrónicos con enlaces de inicio de sesión. Por ahora, abra el correo electrónico con el enlace de inicio de sesión y haga clic en el enlace de inicio de sesión. Serás dirigido al formularioConfirm
.
Ingrese la dirección de correo electrónico que utilizó al iniciar sesión en el formulario
Confirm
. Haga clic en Confirmar . Si la confirmación es exitosa, será dirigido a la páginaProfile
.
Haga clic en el botón Cerrar sesión en la página
Profile
para cerrar sesión. Si el cierre de sesión se realiza correctamente, se le redirigirá de nuevo al formularioLogin
.
Los pasos anteriores capturan el flujo de trabajo de la aplicación.
Opcional: modificar el nombre de su proyecto
Puedes cambiar el nombre de tu proyecto para que los correos electrónicos con enlaces de inicio de sesión enviados por Firebase muestren un nombre "fácil de usar" en lugar de, por ejemplo, project-1078604952662
. Inicie sesión en su cuenta de Firebase y haga clic en Ir a la consola .
- Haga clic en su proyecto de autenticación que aparece en el panel de proyectos de Firebase.
- Haga clic en el ícono de ajustes al lado de Descripción general del proyecto en el menú del panel izquierdo. La pestaña General ya debería estar seleccionada.
- Desplácese hacia abajo hasta la opción Nombre público en la sección Su proyecto .
- Haga clic en el icono de lápiz y modifique el nombre de su proyecto como desee.
- Haga clic en Guardar . Los correos electrónicos con el enlace de inicio de sesión ahora mostrarán el nombre del proyecto actualizado.
Conclusión y próximos pasos
La autenticación sin contraseña parece ser una opción cada vez más popular entre los desarrolladores de aplicaciones, y es comprensible. Más allá de la ventaja obvia de eliminar la necesidad de administrar contraseñas, tampoco hay necesidad de verificación por correo electrónico, ya que el proceso de envío del enlace de inicio de sesión es una verificación en sí mismo.
Al igual que con el proyecto de requisitos previos, la implementación aquí es básica. Podría considerar mejoras simples como:
Bloquear/poner en lista negra dominios de direcciones de correo electrónico concretos (es decir, dominios de correo electrónico no deseado comunes).
Almacenar localmente la dirección de correo electrónico ingresada por el usuario en la página
Login
y verificar la existencia de la dirección de correo electrónico en la páginaConfirm
. Con este enfoque, si el usuario hace clic en un enlace de inicio de sesión en el mismo dispositivo donde accedió a la páginaLogin
, no necesitará ingresar su dirección de correo electrónico nuevamente en la páginaConfirm
, ya que se recuperará. del almacenamiento local. Esto proporciona una experiencia de usuario aún más fluida.
Puede obtener más información sobre la autenticación sin contraseña de Firebase a través de la documentación oficial .