admin管理员组

文章数量:1129681

I'm working on a Flutter application where I need to integrate Microsoft login with multi-factor authentication (MFA). I want to enhance the user experience by remembering the user's email on subsequent logins and conditionally directing the flow based on the email input. Here's the specific flow I want to implement:

1. Initial Login: User logs in using Microsoft login. User enters their email and password (without re-entering the email if they've logged in before) and then completes MFA through the Microsoft Authenticator app.

email pass from this to

after

2. App Restart: Upon reopening the app, open login screen in there the user enters the previously used email, they should directly navigate to the MFA screen. After successful MFA verification, they should navigate to the success screen. For new emails, the standard login flow should apply navigate to microsoft login.

Here its is my code :

import 'package:flutter/material.dart';
import 'package:aad_oauth/aad_oauth.dart';
import 'package:aad_oauth/model/config.dart';
import '../../provider/sign_in_provider.dart';   
import '../SuccessScreen.dart';   

class LoginScreen extends StatefulWidget {
  static final navigatorKey = GlobalKey<NavigatorState>();

  @override
  _LoginScreenState createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {
  final TextEditingController _emailController = TextEditingController();
  late final AadOAuth oauth;

  @override
  void initState() {
    super.initState();
    final config = Config(
      tenant: '2f5964b2-44fc-420d-8974-7afab2XXXX',
      clientId: 'ed4c80e3-847b-4b0a-85a9-c96862096XX',
      scope: 'openid profile email',
      redirectUri: '',
      navigatorKey: SignInProvider.navigatorKey, 
    );
    oauth = AadOAuth(config);
  }

  void _login() async {
    try {
      await oauth.login();
      final accessToken = await oauth.getAccessToken();
      if (accessToken != null) {
        Navigator.pushReplacement(
          context,
          MaterialPageRoute(builder: (context) => SuccessScreen()),
        );
      }
    } catch (e) {
      _showLoginError(e.toString());
    }
  }

  void _showLoginError(String message) {
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: Text('Login Error'),
        content: Text(message),
        actions: [
          TextButton(
            child: Text('OK'),
            onPressed: () => Navigator.of(context).pop(),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: EdgeInsets.all(24.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            SizedBox(height: 20),
            Text(
              'Sign in',
              style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
              textAlign: TextAlign.center,
            ),
            SizedBox(height: 20),
            TextField(
              controller: _emailController,
              decoration: InputDecoration(
                labelText: 'Email, phone, or Skype',
                border: OutlineInputBorder(),
                filled: true,
                fillColor: Colors.white,
              ),
              keyboardType: TextInputType.emailAddress,
            ),
            SizedBox(height: 16),
            ElevatedButton(
              onPressed: _login,
              child: Padding(
                padding: EdgeInsets.symmetric(vertical: 12),
                child: Text(
                  'Next',
                  style: TextStyle(fontSize: 16),
                ),
              ),
              style: ElevatedButton.styleFrom(
                backgroundColor: Colors.blue[700], // Background color
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(4),
                ),
              ),
            ),
            SizedBox(height: 16),
           
          ],
        ),
      ),
    );
  }

  @override
  void dispose() {
    _emailController.dispose();
    super.dispose();
  }
}

How can I implement this conditional navigation based on the user's email input effectively in Flutter and are there best practices or specific Flutter packages that would facilitate the management of user sessions and MFA interactions, especially with Microsoft Azure's authentication services?

Any insights or guidance on how to achieve this in Flutter would be greatly appreciated!

本文标签: