admin管理员组文章数量:1355555
I am working on a Flutter project where I am trying to implement authentication using Amazon Cognito. I am facing issues with the authentication flow, and the app is stuck in an endless waiting state when attempting to authenticate users. I am using GoRouter for routing and StreamBuilder / FutureBuilder to manage authentication state. However, the user is not being properly authenticated, and the page doesn’t load as expected.
Here are the files I am working with:
- main.dart (App entry point, router setup)
- auth_controller.dart (Handles authentication logic)
- login_controller.dart (Handles login logic)
- sign_up_controller.dart (Handles signup logic)
- login_screen.dart (Login UI)
- auth_service.dart (Interacts with Cognito for authentication)
- login_form.dart (Login form widget)
The problem: When I try to authenticate, it stays in the loading state indefinitely. I cannot access the login page, and it seems the Stream in authStateChanges is not emitting any data, causing the app to remain stuck in the waiting state.
The following code snippets illustrate the setup:
main
import 'package:checkee/theme/theme.dart';
import 'package:flutter/material.dart';
import 'core/router.dart'; // Importer router.dart pour gérer la logique de routage
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp.router(
title: 'Checkee',
theme: checkeeTheme,
routerConfig: appRouter, // Utiliser appRouter configuré dans router.dart
);
}
}
auth_controller
import 'dart:async';
import 'package:amazon_cognito_identity_dart_2/cognito.dart';
class AuthController {
final userPool = CognitoUserPool(
'eu-west-1_eYRgcALYR', // Remplace par ton User Pool ID
'rih16pulnrf9ihflpqiobjomk', // Remplace par ton App Client ID
);
final _authStateController = StreamController<CognitoUser?>.broadcast();
// Connexion de l'utilisateur
Future<CognitoUserSession?> signInWithEmailPassword(String email, String password) async {
try {
final cognitoUser = CognitoUser(email, userPool);
final authDetails = AuthenticationDetails(
username: email,
password: password,
);
final session = await cognitoUser.authenticateUser(authDetails);
_authStateController.add(cognitoUser); // Envoie l'utilisateur dans le stream
return session;
} catch (e) {
print("Erreur de connexion avec Cognito : $e");
_authStateController.add(null); // Envoie null en cas d'échec
return null;
}
}
// Fonction pour surveiller l'état de l'authentification
Stream<CognitoUser?> authStateChanges() {
return _authStateController.stream;
}
// Méthode pour se déconnecter
Future<void> signOut() async {
_authStateController.add(null); // Met à jour le stream avec null pour indiquer la déconnexion
}
// Récupère le type d'utilisateur (locataire, propriétaire, etc.)
Future<String> getUserType(String username) async {
final cognitoUser = CognitoUser(username, userPool);
final session = await cognitoUser.getSession();
final userGroups = await getUserGroups(session!);
if (userGroups.contains('Propriétaire')) {
return 'Propriétaire';
} else if (userGroups.contains('Locataire')) {
return 'Locataire';
}
return 'Locataire'; // Par défaut
}
// Récupère les groupes de l'utilisateur
Future<List<String>> getUserGroups(CognitoUserSession session) async {
final idToken = session.idToken;
final claims = idToken.payload;
final groups = claims['cognito:groups'] as List<dynamic>? ?? [];
return groups.map((group) => group.toString()).toList();
}
}
login_controller
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import '../services/auth_service.dart'; // Assurez-vous que AuthService est correctement importé
class LoginController {
final TextEditingController emailController;
final TextEditingController passwordController;
LoginController({
required this.emailController,
required this.passwordController,
});
Future<void> login(BuildContext context) async {
try {
final session = await AuthService().signInWithEmailPassword(
emailController.text,
passwordController.text,
);
if (session != null) {
// Vérifie le groupe de l'utilisateur via Cognito et redirige en fonction du rôle
final userGroups = await AuthService().getUserGroups(session);
if (userGroups.contains('Admin')) {
context.go('/adminHome'); // Rediriger vers la page Admin
} else if (userGroups.contains('Propriétaire')) {
context.go('/ownerHome'); // Rediriger vers la page Propriétaire
} else if (userGroups.contains('Locataire')) {
context.go('/tenantHome'); // Rediriger vers la page Locataire
} else {
context.go('/'); // Redirection par défaut si aucun groupe spécifique
}
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Email ou mot de passe invalide')),
);
}
} catch (e) {
print("Erreur de connexion avec Cognito : $e");
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Erreur de connexion : $e')),
);
}
}
void dispose() {
emailController.dispose();
passwordController.dispose();
}
}
sign_up_controller
import '../services/auth_service.dart'; // Assurez-vous que AuthService est importé
class SignUpController {
final AuthService _authService = AuthService();
Future<String?> signUp({
required String email,
required String password,
required String firstName,
required String lastName,
required String phoneNumber,
String? address,
String? tvaNumber,
required String userType,
}) async {
try {
// Appel à la méthode signUpWithEmailPassword d'AuthService pour créer un utilisateur
final errorMessage = await _authService.signUpWithEmailPassword(email, password);
if (errorMessage != null) {
return errorMessage; // Retourner un message d'erreur si l'inscription échoue
}
// Ajouter les autres informations utilisateur si l'inscription réussit
// Par exemple, enregistrer ces informations dans une base de données
return null; // Inscription réussie
} catch (e) {
print("Erreur lors de l'inscription : $e");
return 'Erreur lors de l\'inscription'; // Message générique en cas d'échec
}
}
}
login_screen
import 'package:flutter/material.dart';
import 'package:checkee/features/auth/controllers/login_controller.dart'; // Assurez-vous d'avoir la référence du login_controller.dart
class LoginScreen extends StatelessWidget {
final TextEditingController emailController = TextEditingController();
final TextEditingController passwordController = TextEditingController();
@override
Widget build(BuildContext context) {
final loginController = LoginController(
emailController: emailController,
passwordController: passwordController,
);
return Scaffold(
appBar: AppBar(title: Text('Login')),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
TextField(
controller: emailController,
decoration: InputDecoration(labelText: 'Email'),
),
TextField(
controller: passwordController,
decoration: InputDecoration(labelText: 'Password'),
obscureText: true,
),
ElevatedButton(
onPressed: () async {
await loginController.login(context); // Appel de la méthode login() de LoginController
},
child: Text('Login'),
),
],
),
),
);
}
}
auth_service
import 'dart:async';
import 'package:amazon_cognito_identity_dart_2/cognito.dart';
class AuthService {
final userPool = CognitoUserPool(
'eu-west-1_eYRgcALYR', // Remplace par ton User Pool ID
'rih16pulnrf9ihflpqiobjomk', // Remplace par ton App Client ID
);
final _authStateController = StreamController<CognitoUser?>.broadcast();
// Connexion de l'utilisateur
Future<CognitoUserSession?> signInWithEmailPassword(String email, String password) async {
try {
final cognitoUser = CognitoUser(email, userPool);
final authDetails = AuthenticationDetails(
username: email,
password: password,
);
final session = await cognitoUser.authenticateUser(authDetails);
_authStateController.add(cognitoUser); // Envoie l'utilisateur dans le stream
return session;
} catch (e) {
print("Erreur de connexion avec Cognito : $e");
_authStateController.add(null); // Envoie null en cas d'échec
return null;
}
}
// Inscription de l'utilisateur
Future<String?> signUpWithEmailPassword(String email, String password) async {
try {
final userAttributes = [
AttributeArg(name: 'email', value: email),
];
final signUpResult = await userPool.signUp(email, password, userAttributes: userAttributes);
if (signUpResult != null) {
return null; // Inscription réussie
} else {
return 'Erreur lors de la création de l\'utilisateur';
}
} catch (e) {
print("Erreur lors de l'inscription : $e");
return e.toString();
}
}
// Récupère la session d'un utilisateur avec son email
Future<CognitoUserSession?> getSession(String email) async {
final cognitoUser = CognitoUser(email, userPool);
try {
final session = await cognitoUser.getSession();
return session; // Retourne la session si disponible
} catch (e) {
print("Erreur lors de la récupération de la session : $e");
return null; // Retourne null en cas d'erreur
}
}
// Méthode pour récupérer les groupes de l'utilisateur à partir de la session
Future<List<String>> getUserGroups(CognitoUserSession session) async {
try {
final idToken = session.idToken; // On accède au ID token
final claims = idToken.payload; // Récupère les claims de l'ID token
// Récupérer les groupes à partir des claims (s'il y en a)
final groups = claims['cognito:groups'] as List<dynamic>? ?? [];
return groups.map((group) => group.toString()).toList(); // Convertir en liste de chaînes
} catch (e) {
print("Erreur de récupération des groupes : $e");
return [];
}
}
// Fonction de déconnexion
Future<void> signOut() async {
_authStateController.add(null); // Envoie null dans le stream lors de la déconnexion
}
// Fonction pour surveiller l'état de l'authentification
Stream<CognitoUser?> authStateChanges() {
return _authStateController.stream;
}
}
本文标签:
版权声明:本文标题:Issues with User Authentication using Cognito in Flutter (GoRouter, StreamBuilder, and FutureBuilder) - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1743935239a2564540.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论