How to redirect to the next page after successful authentication in flutter

0

Context:

I am building a simple login app using azure AD, after clicking the login button the app authenticates but doesn't not render the next screen but the login button disappears. I want to redirect to the next page after a successful login, but am not being able to. I have handled the navigation inside the initState method inside the StatefulWidget but for some reason it is not being called. How would I be able to solve this?

code

class _SignInState extends State<SignIn> {
  static const String SCOPE ='';
  static const String TENANT_ID = 'organizations';
  static String authority = "";

  MsalMobile msal;
  bool isSignedIn = false;

  @override
  void initState() {
    super.initState();
    MsalMobile.create('assets/auth_config.json', authority).then((client) {
      setState(() {
        msal = client;
      });
      refreshSignedInStatus();
      signInNavigation();
    });
  }

  Future<void> signInNavigation() async {
    isSignedIn = await handleSignIn();

    if(isSignedIn) {
      // Your navigation code
      Navigator.of(context).pushReplacement(
          MaterialPageRoute(
              builder: (context) => NavScreen()));
    }
  }
  /// Updates the signed in state
  refreshSignedInStatus() {
    msal.getSignedIn().then((loggedIn) {
      print('refreshing');
      setState(() {
        isSignedIn = loggedIn;
      });
    });
  }

  /// Signs a user in
  handleSignIn() async {
    await msal.signIn(null, [SCOPE]).then((result) {
      refreshSignedInStatus();
    }).catchError((exception) {
      if (exception is MsalMobileException) {
        logMsalMobileError(exception);
      } else {
        final ex = exception as Exception;
        print('exception occurred');
        print(ex.toString());
      }
    });
  }

  logMsalMobileError(MsalMobileException exception) {
    print('${exception.errorCode}: ${exception.message}');
    if (exception.innerException != null) {
      print(
          'inner exception = ${exception.innerException.errorCode}: ${exception.innerException.message}');
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: new Scaffold(
          body: Builder(
            builder: (context) => Stack(
              fit: StackFit.expand,
              children: <Widget>[
                Container(
                  width: MediaQuery.of(context).size.width,
                  height: MediaQuery.of(context).size.height,
                  child: Image.asset('assets/landing.webp',
                      fit: BoxFit.fill,
                      color: Color.fromRGBO(255, 255, 255, 0.6),
                      colorBlendMode: BlendMode.modulate),
                ),
                Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    SizedBox(height: 10.0),
                    Container(
                      width: 130.0,
                      child: Align(
                          alignment: Alignment.center,
                          child: RaisedButton(
                            shape: RoundedRectangleBorder(
                                borderRadius: new BorderRadius.circular(30.0)),
                            color: Color(0xffffffff),
                            child: Row(
                              mainAxisAlignment: MainAxisAlignment.start,
                              children: <Widget>[
                                Visibility(
                                  visible: !isSignedIn,
                                  child: RaisedButton(
                                    child: Text("Sign In"),
                                    onPressed: handleSignIn,
                                  ),
                                ),
                              ],
                            ),
                          )),
                    )
                  ],
                ),
              ],
            ),
          ),
        ));
  }
}

I don't know how to resolve this issue, am stuck

msal.sign method

Future<MsalMobileAuthenticationResultPayload> signIn(
      String loginHint, List<String> scopes) async {
    if (!initialized) {
      throw MsalMobileException.fromErrorCode(
          MsalMobileExceptionErrorCode.notInitialized);
    }

    final response = await _channel.invokeMethod(
      'signIn',
      <String, dynamic>{'loginHint': loginHint, 'scopes': scopes},
    );
    final result = response != null
        ? MsalMobileAuthenticationResult.fromJson(jsonDecode(response))
        : null;
    if (!result.isSuccess && result.exception != null) {
      // check if the user is already signed in.  That could be the cause of an invalid_parameter failure from MSAL
      final signedIn = await this.getSignedIn();
      if (signedIn) {
        throw MsalMobileException.fromErrorCode(
            MsalMobileExceptionErrorCode.alreadySignedIn);
      }
      throw MsalMobileException.copy(result.exception, result.innerException);
    }
    return result.payload;
  }
flutter
dart
asked on Stack Overflow Nov 10, 2020 by blackbird • edited Nov 10, 2020 by blackbird

1 Answer

1
/// Updates the signed in state
  refreshSignedInStatus() {
    msal.getSignedIn().then((loggedIn) {
      print('refreshing');
      setState(() {
        isSignedIn = loggedIn;
      });
      
      if(isSignedIn) {
        // Your navigation code
        Navigator.of(context).pushReplacement(
          MaterialPageRoute(
            builder: (context) => NavScreen()));
      }

    });
  }

A good way to implement authentication is to display a CircularProgressIndicator while we check from the backend whether the user is signed in & once it's done, we can display the Login/Sign up or the Home screen depending upon the status.

answered on Stack Overflow Nov 10, 2020 by Ravi Singh Lodhi

User contributions licensed under CC BY-SA 3.0