web-dev-qa-db-fra.com

Flutter: connectez-vous via une vue Web

Je suis assez nouveau pour Flutter. Existe-t-il un moyen de se connecter via une vue Web dans notre application?

par exemple. Dans la première page, il y a cette vue Web où nous pouvons faire la connexion. Une fois connecté, l'application nous emmène dans une deuxième page où nous pouvons faire d'autres choses.

10
Little Monkey

Dans mon application, j'utilise l'authentification implicite instagram, ce qui implique de se connecter à l'utilisateur dans la vue Web et d'obtenir un jeton depuis l'URL de redirection. J'utilise flutter_webview_plugin Le code suivant crée WebviewScaffold avec l'URL de connexion. Et il écoute les changements d'URL. Ainsi, lorsque la réponse est redirigée vers mon redirectUrl, elle analyse l'URL pour obtenir le jeton. Ensuite, vous devez enregistrer le jeton pour les demandes suivantes dans l'application.

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

Vous pouvez utiliser mon plugin flutter_inappwebview , qui est un plugin Flutter qui vous permet d'ajouter des WebViews en ligne ou d'ouvrir une fenêtre de navigateur dans l'application et qui possède de nombreux événements, méthodes et options pour contrôler les WebViews.

Vous pouvez utiliser les événements onLoadStart ou onLoadStop pour détecter les modifications d'URL. Par exemple, vous pouvez obtenir le jeton:

  • de l'url
  • des cookies
  • de localStorage

Exemple complet:

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
Lorenzo Pichilli