Flutter:通过网络视图登录

时间:2018-07-26 14:27:55

标签: login webview flutter

我对Flutter很陌生。 是否可以通过网络视图登录到我们的应用?

例如在第一页中,有此Web视图,我们可以在其中进行登录。登录后,该应用程序将带我们进入第二页,我们可以在其中执行其他操作。

2 个答案:

答案 0 :(得分:4)

在我的应用中,我使用instagram隐式身份验证,这意味着要在Webview中登录用户并从重定向URL获取令牌。我使用flutter_webview_plugin 接下来的代码使用登录URL构建WebviewScaffold。并监听网址更改。因此,当响应重定向到我的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..."),
        ));
  }
}

答案 1 :(得分:2)

您可以使用我的插件flutter_inappwebview,它是Flutter插件,允许您添加内联WebView或打开应用程序内浏览器窗口,并具有许多事件,方法和选项来控制WebView。

您可以使用onLoadStartonLoadStop事件来检测URL更改。例如,您可以获取令牌:

  • 来自网址
  • 来自cookie
  • 来自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);
                      }
                    },
                  ),
                ),
              ),
            ]))
    );
  }
}
相关问题