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;
}
/// 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.
User contributions licensed under CC BY-SA 3.0