Reputation: 2787
I'm not sure if this is the appropriate stack exchange site but I think it fits more of here than the others that I can think of. Anyways, I work for a mobile app development team and we're looking into using Flutter to develop our future mobile apps as it reduces the amount of work needed when developing for both iOS and Android (we're just a small team).
I read through a bit about Flutter and checked the available packages and the Dart/Flutter Pub and there are some packages that aren't available yet for Flutter that we use for Android and iOS. Take MSAL (Microsoft Authentication Library) for example. After reading through the documentation, I read about Platform Channels and how you can run some KT/Swift etc specific code and return it through something like the MethodChannel
in Kotlin but the example from the Flutter docs show an example of only returning specific data types or simple values. What if I wanted to authenticate a user using MSAL? that would involve some UI work that doesn't happen in Flutter specifically since it relies on either the browser or a webview (depending on your MSAL config)
My question here is probably gonna be in 2 main things:
Note:
I'm aware that there are packages for authentication in the Dart Pub but I'm just using MSAL as an example, we also use other packages that kind of rely on displaying custom views to authenticate users.
Upvotes: 1
Views: 1464
Reputation: 2787
I got this to work using platform channels. To answer my specific questions:
FlutterActivity
after authenticating my user.Activity
myself but the package was able to open its own webview so it should workMainActivity
private val LOGIN_CHANNEL = "flutter.android/msal"
private val scopes = arrayOf("https://graph.microsoft.com/User.Read", "https://graph.microsoft.com/User.ReadBasic.All")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
GeneratedPluginRegistrant.registerWith(this)
MyLibrary.setupClientApp(applicationContext, R.raw.auth_config, scopes)
MethodChannel(flutterView, LOGIN_CHANNEL).setMethodCallHandler { call, result ->
if (call.method == "login") {
login{
result.success(it)
}
}
}
}
private fun login(callback: (String?) -> Unit) {
MyLibrary.instance!!.acquireToken(
this,
scopes,
MyLibrary.getAuthInteractiveCallback {
callback(MyLibrary.getUser()?.displayName)
}
)
}
MyHomePage (State)
class _MyHomePageState extends State<MyHomePage> {
String _responseFromNativeCode = "";
static const platform = const MethodChannel('flutter.android/msal');
Future _login() async {
String response = "";
try {
response = await platform.invokeMethod('login');
} on PlatformException catch (e) {
response = "Failed to Invoke: '${e.message}'.";
}
setState(() {
_responseFromNativeCode = response;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'Hi $_responseFromNativeCode',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _login,
tooltip: 'Login',
child: Icon(Icons.lock),
),
);
}
}
Upvotes: 1