Flutterは初めてです。アプリにウェブビューからログインする方法はありますか?
例えば最初のページには、ログインを行うことができるこのWebビューがあります。ログインした後、アプリは2番目のページに移動し、そこで他のことができます。
私のアプリでは、instagramの暗黙の認証を使用しています。これは、webviewにユーザーをログインさせ、リダイレクトURLからトークンを取得することを意味します。私は flutter_webview_plugin を使用します次のコードは、ログインURLを使用してWebviewScaffoldを構築します。そして、URLの変更をリッスンします。したがって、応答が私のredirectUrlにリダイレクトされると、URLを解析してトークンを取得します。次に、アプリで次のリクエストのトークンを保存する必要があります。
import 'Dart:async';
import 'package:flutter/material.Dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.Dart';
class LoginScreen extends StatefulWidget {
@override
_LoginScreenState createState() => new _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
final flutterWebviewPlugin = new FlutterWebviewPlugin();
StreamSubscription _onDestroy;
StreamSubscription<String> _onUrlChanged;
StreamSubscription<WebViewStateChanged> _onStateChanged;
String token;
@override
void dispose() {
// Every listener should be canceled, the same should be done with this stream.
_onDestroy.cancel();
_onUrlChanged.cancel();
_onStateChanged.cancel();
flutterWebviewPlugin.dispose();
super.dispose();
}
@override
void initState() {
super.initState();
flutterWebviewPlugin.close();
// Add a listener to on destroy WebView, so you can make came actions.
_onDestroy = flutterWebviewPlugin.onDestroy.listen((_) {
print("destroy");
});
_onStateChanged =
flutterWebviewPlugin.onStateChanged.listen((WebViewStateChanged state) {
print("onStateChanged: ${state.type} ${state.url}");
});
// Add a listener to on url changed
_onUrlChanged = flutterWebviewPlugin.onUrlChanged.listen((String url) {
if (mounted) {
setState(() {
print("URL changed: $url");
if (url.startsWith(Constants.redirectUri)) {
RegExp regExp = new RegExp("#access_token=(.*)");
this.token = regExp.firstMatch(url)?.group(1);
print("token $token");
saveToken(token);
Navigator.of(context).pushNamedAndRemoveUntil(
"/home", (Route<dynamic> route) => false);
flutterWebviewPlugin.close();
}
});
}
});
}
@override
Widget build(BuildContext context) {
String loginUrl = "someservise.com/auth";
return new WebviewScaffold(
url: loginUrl,
appBar: new AppBar(
title: new Text("Login to someservise..."),
));
}
}
私のプラグイン flutter_inappwebview を使用できます。これは、インラインWebViewを追加したり、アプリ内ブラウザーウィンドウを開いたりすることができるFlutterプラグインであり、WebViewを制御するための多くのイベント、メソッド、およびオプションがあります。
onLoadStart
またはonLoadStop
イベントを使用して、URLの変更を検出できます。たとえば、トークンを取得できます。
完全な例:
import 'Dart:async';
import 'package:flutter/material.Dart';
import 'package:flutter_inappwebview/flutter_inappwebview.Dart';
Future main() async {
runApp(new MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: InAppWebViewPage()
);
}
}
class InAppWebViewPage extends StatefulWidget {
@override
_InAppWebViewPageState createState() => new _InAppWebViewPageState();
}
class _InAppWebViewPageState extends State<InAppWebViewPage> {
InAppWebViewController webView;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("InAppWebView")
),
body: Container(
child: Column(children: <Widget>[
Expanded(
child: Container(
child: InAppWebView(
initialUrl: "https://myUrl.com",
initialHeaders: {},
initialOptions: InAppWebViewWidgetOptions(
inAppWebViewOptions: InAppWebViewOptions(
debuggingEnabled: true,
),
androidInAppWebViewOptions: AndroidInAppWebViewOptions(
domStorageEnabled: true,
databaseEnabled: true,
),
),
onWebViewCreated: (InAppWebViewController controller) {
webView = controller;
},
onLoadStart: (InAppWebViewController controller, String url) {
},
onLoadStop: (InAppWebViewController controller, String url) async {
if (url.startsWith("https://myUrl.com/auth-response")) {
// get your token from url
RegExp regExp = new RegExp("access_token=(.*)");
String token = regExp.firstMatch(url)?.group(1);
print(token);
// or using CookieManager
CookieManager cookieManager = CookieManager.instance();
Cookie token = await cookieManager.getCookie(url: "https://myUrl.com/auth-response", name: "access_token");
print(token.value);
// or using javascript to get access_token from localStorage
String token = await controller.evaluateJavascript(source: "localStorage.getItem('access_token')");
print(token);
}
},
),
),
),
]))
);
}
}