web-dev-qa-db-ja.com

Flutter:ウェブビューからログイン

Flutterは初めてです。アプリにウェブビューからログインする方法はありますか?

例えば最初のページには、ログインを行うことができるこのWebビューがあります。ログインした後、アプリは2番目のページに移動し、そこで他のことができます。

10
Little Monkey

私のアプリでは、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..."),
        ));
  }
}
14
Marica

私のプラグイン flutter_inappwebview を使用できます。これは、インラインWebViewを追加したり、アプリ内ブラウザーウィンドウを開いたりすることができるFlutterプラグインであり、WebViewを制御するための多くのイベント、メソッド、およびオプションがあります。

onLoadStartまたはonLoadStopイベントを使用して、URLの変更を検出できます。たとえば、トークンを取得できます。

  • uRLから
  • クッキーから
  • localStorageから

完全な例:

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);
                      }
                    },
                  ),
                ),
              ),
            ]))
    );
  }
}
2