Cómo gestionar el estado de autenticación y proteger las rutas de tu app Flutter

La gestión del estado de autenticación es esencial para asegurar que los usuarios puedan acceder solo a las partes de la aplicación que les correspondan. En Flutter, podemos gestionar el estado de autenticación y proteger las rutas mediante la integración de Firebase Authentication y una gestión eficiente del estado, lo que garantiza que las rutas de tu aplicación estén protegidas de forma dinámica según el estado de inicio de sesión del usuario.

En este artículo, aprenderás cómo gestionar el estado de autenticación en tiempo real y cómo proteger las rutas de tu aplicación para que solo los usuarios autenticados puedan acceder a determinadas pantallas.


🚀 Paso 1: Integrar Firebase Auth en tu aplicación

Si aún no has integrado Firebase en tu proyecto Flutter, asegúrate de tener las dependencias correctas en tu archivo pubspec.yaml:

dependencies:
firebase_core: ^2.25.0
firebase_auth: ^4.15.0
provider: ^6.0.3

Ejecuta:

flutter pub get

🧩 Paso 2: Crear un servicio de autenticación

Un enfoque limpio y modular consiste en crear un servicio de autenticación que gestione el flujo de inicio de sesión, cierre de sesión y monitoreo del estado de autenticación.

Crea un archivo auth_service.dart:

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
// Crear usuario con correo y contraseña
Future<User?> signUpWithEmailPassword(String email, String password) async {
try {
UserCredential userCredential = await _auth.createUserWithEmailAndPassword(
email: email,
password: password,
);
return userCredential.user;
} catch (e) {
print('Error al registrar usuario: $e');
return null;
}
}
// Iniciar sesión con correo y contraseña
Future<User?> signInWithEmailPassword(String email, String password) async {
try {
UserCredential userCredential = await _auth.signInWithEmailAndPassword(
email: email,
password: password,
);
return userCredential.user;
} catch (e) {
print('Error al iniciar sesión: $e');
return null;
}
}
// Cerrar sesión
Future<void> signOut() async {
await _auth.signOut();
}
// Estado de autenticación en tiempo real
Stream<User?> get user {
return _auth.authStateChanges();
}
}

Este servicio proporciona las funciones necesarias para manejar la autenticación de usuarios, incluida la observación del estado de autenticación mediante authStateChanges().


🔒 Paso 3: Proteger las rutas con un StreamBuilder

Para gestionar el estado de autenticación y redirigir al usuario según si está autenticado o no, utilizamos un StreamBuilder que escucha los cambios en el estado de autenticación. Esto permite redirigir automáticamente a la pantalla correcta, como la de inicio de sesión o la pantalla principal.

En tu main.dart, implementa el siguiente código para gestionar las rutas de tu aplicación:

import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:provider/provider.dart';
import 'auth_service.dart';
import 'home_screen.dart';
import 'login_screen.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (_) => AuthService(),
child: MaterialApp(
title: 'Autenticación Flutter',
theme: ThemeData(primarySwatch: Colors.blue),
home: AuthWrapper(),
),
);
}
}
class AuthWrapper extends StatelessWidget {
@override
Widget build(BuildContext context) {
final user = FirebaseAuth.instance.currentUser;
// Si hay un usuario autenticado, redirige a la pantalla principal
if (user != null) {
return HomeScreen();
} else {
// Si no hay un usuario autenticado, redirige a la pantalla de login
return LoginScreen();
}
}
}

En este caso, el AuthWrapper detecta si hay un usuario autenticado y redirige a la pantalla correspondiente (HomeScreen si está autenticado o LoginScreen si no lo está).


🔑 Paso 4: Implementar la protección de rutas específicas

Ahora que tenemos un StreamBuilder que escucha el estado de autenticación, es posible proteger rutas específicas dentro de la aplicación. Solo aquellos usuarios autenticados pueden acceder a rutas protegidas.

Por ejemplo, supongamos que deseas proteger la pantalla HomeScreen y permitir solo a usuarios autenticados el acceso a ella. Puedes usar el siguiente código para verificar si el usuario está autenticado antes de permitirle acceder a la pantalla:

class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final user = FirebaseAuth.instance.currentUser;
if (user == null) {
return LoginScreen(); // Redirige al login si no está autenticado
}
return Scaffold(
appBar: AppBar(title: Text('Pantalla Principal')),
body: Center(
child: ElevatedButton(
onPressed: () {
FirebaseAuth.instance.signOut();
},
child: Text('Cerrar sesión'),
),
),
);
}
}

🎯 Paso 5: Protección adicional con reglas de seguridad en Firestore

No solo debes proteger las rutas de la aplicación, sino también garantizar que los datos en Firestore estén correctamente asegurados. Puedes hacerlo utilizando reglas de seguridad de Firebase Firestore, que permitan el acceso solo a los usuarios autenticados.

En Firestore, puedes configurar reglas como estas:

rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /posts/{postId} {
allow read, write: if request.auth != null;
}
}
}

Estas reglas aseguran que solo los usuarios autenticados puedan leer y escribir en la colección posts.


🎉 Conclusión

Gestionar el estado de autenticación y proteger las rutas en Flutter con Firebase es un proceso sencillo que te permitirá crear aplicaciones más seguras y funcionales. Con los pasos anteriores, puedes asegurarte de que solo los usuarios autenticados accedan a partes críticas de tu aplicación, mientras que las rutas públicas estarán abiertas para todos.

Comentarios

Entradas más populares de este blog

Cómo manejar notificaciones push avanzadas con Firebase Cloud Messaging y Flutter

Cómo usar Firestore en Flutter para guardar y mostrar datos en tiempo real.