flutter_web_auth_2 5.0.1 copy "flutter_web_auth_2: ^5.0.1" to clipboard
flutter_web_auth_2: ^5.0.1 copied to clipboard

Flutter plugin for authenticating a user with a web service.

example/lib/main.dart

import 'dart:async';
import 'dart:io' show HttpServer;

import 'package:desktop_webview_window/desktop_webview_window.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_web_auth_2/flutter_web_auth_2.dart';

const _html = '''
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Grant Access to Flutter</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>
    html, body { margin: 0; padding: 0; }

    main {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      min-height: 100vh;
      font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;
    }

    #icon {
      font-size: 96pt;
    }

    #text {
      padding: 2em;
      max-width: 260px;
      text-align: center;
    }

    #button a {
      display: inline-block;
      padding: 6px 12px;
      color: white;
      border: 1px solid rgba(27,31,35,.2);
      border-radius: 3px;
      background-image: linear-gradient(-180deg, #34d058 0%, #22863a 90%);
      text-decoration: none;
      font-size: 14px;
      font-weight: 600;
    }

    #button a:active {
      background-color: #279f43;
      background-image: none;
    }
  </style>
</head>
<body>
  <main>
    <div id="icon">&#x1F3C7;</div>
    <div id="text">Press the button below to sign in using your localhost account.</div>
    <div id="button"><a href="/?originalUrl=https%3A%2F%2Fpub.dev%2F%26quot%3BCALLBACK_URL_HERE%26quot%3B%26gt%3BSign%2520in%26lt%3B%26%2347%3Ba%26gt%3B%26lt%3B%26%2347%3Bdiv%26gt%3B%2520%2520%26lt%3B%26%2347%3Bmain%26gt%3B%26lt%3B%26%2347%3Bbody%26gt%3B%26lt%3B%26%2347%3Bhtml%26gt%3B%26%2339%3B%26%2339%3B%26%2339%3B%3Bvoid%2520main(List%26lt%3BString%26gt%3B%2520args)%2520%7B%2520%2520if%2520(runWebViewTitleBarWidget(args))%2520%7B%2520%2520%2520%2520return%3B%2520%2520%7D%2520%2520runApp(const%2520MyApp())%3B%7Dclass%2520MyApp%2520extends%2520StatefulWidget%2520%7B%2520%2520const%2520MyApp(%7Bsuper.key%7D)%3B%2520%2520%40override%2520%2520MyAppState%2520createState()%2520%3D%26gt%3B%2520MyAppState()%3B%7Dclass%2520MyAppState%2520extends%2520State%26lt%3BMyApp%26gt%3B%2520%7B%2520%2520String%2520_status%2520%3D%2520%26%2339%3B%26%2339%3B%3B%2520%2520%40override%2520%2520void%2520initState()%2520%7B%2520%2520%2520%2520super.initState()%3B%2520%2520%2520%2520if%2520(!kIsWeb)%2520%7B%2520%2520%2520%2520%2520%2520startServer()%3B%2520%2520%2520%2520%7D%2520%2520%7D%2520%2520Future%26lt%3Bvoid%26gt%3B%2520startServer()%2520async%2520%7B%2520%2520%2520%2520final%2520server%2520%3D%2520await%2520HttpServer.bind(%26%2339%3B127.0.0.1%26%2339%3B%2C%252043823)%3B%2520%2520%2520%2520server.listen((req)%2520async%2520%7B%2520%2520%2520%2520%2520%2520setState(()%2520%7B%2520%2520%2520%2520%2520%2520%2520%2520_status%2520%3D%2520%26%2339%3BReceived%2520request!%26%2339%3B%3B%2520%2520%2520%2520%2520%2520%7D)%3B%2520%2520%2520%2520%2520%2520req.response.headers.add(%26%2339%3BContent-Type%26%2339%3B%2C%2520%26%2339%3Btext%26%2347%3Bhtml%26%2339%3B)%3B%2520%2520%2520%2520%2520%2520req.response.write(%2520%2520%2520%2520%2520%2520%2520%2520_html.replaceFirst(%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%26%2339%3BCALLBACK_URL_HERE%26%2339%3B%2C%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%26%2339%3Bfoobar%3A%26%2347%3B%26%2347%3Bsuccess%3Fcode%3D1337%26%2339%3B%2C%2520%2520%2520%2520%2520%2520%2520%2520)%2C%2520%2520%2520%2520%2520%2520)%3B%2520%2520%2520%2520%2520%2520await%2520req.response.close()%3B%2520%2520%2520%2520%7D)%3B%2520%2520%7D%2520%2520Future%26lt%3Bvoid%26gt%3B%2520authenticate()%2520async%2520%7B%2520%2520%2520%2520setState(()%2520%7B%2520%2520%2520%2520%2520%2520_status%2520%3D%2520%26%2339%3B%26%2339%3B%3B%2520%2520%2520%2520%7D)%3B%2520%2520%2520%2520%26%2347%3B%26%2347%3B%2520Normally%2C%2520you%2520don%26%2339%3Bt%2520need%2520to%2520specify%2520a%2520custom%2520URL%2520on%2520web.%2520However%2C%2520in%2520%2520%2520%2520%26%2347%3B%26%2347%3B%2520this%2520example%2C%2520we%2520just%2520go%2520the%2520auth%2520page%2520directly%2520since%2520we%2520cannot%2520start%2520%2520%2520%2520%26%2347%3B%26%2347%3B%2520the%2520socket%2520server...%2520%2520%2520%2520final%2520url%2520%3D%2520kIsWeb%2520%3F%2520%26%2339%3B%24%7BUri.base%7Dauth.html%26%2339%3B%2520%3A%2520%26%2339%3Bhttp%3A%26%2347%3B%26%2347%3B127.0.0.1%3A43823%26%2347%3B%26%2339%3B%3B%2520%2520%2520%2520try%2520%7B%2520%2520%2520%2520%2520%2520final%2520result%2520%3D%2520await%2520FlutterWebAuth2.authenticate(%2520%2520%2520%2520%2520%2520%2520%2520url%3A%2520url%2C%2520%2520%2520%2520%2520%2520%2520%2520callbackUrlScheme%3A%2520%26%2339%3Bfoobar%26%2339%3B%2C%2520%2520%2520%2520%2520%2520%2520%2520options%3A%2520const%2520FlutterWebAuth2Options(%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520timeout%3A%25205%2C%2520%26%2347%3B%26%2347%3B%2520example%3A%25205%2520seconds%2520timeout%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%26%2347%3B%26%2347%3BSet%2520Android%2520Browser%2520priority%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%26%2347%3B%26%2347%3B%2520customTabsPackageOrder%3A%2520%5B%26%2339%3Bcom.android.chrome%26%2339%3B%5D%2C%2520%2520%2520%2520%2520%2520%2520%2520)%2C%2520%2520%2520%2520%2520%2520)%3B%2520%2520%2520%2520%2520%2520setState(()%2520%7B%2520%2520%2520%2520%2520%2520%2520%2520_status%2520%3D%2520%26%2339%3BGot%2520result%3A%2520%24result%26%2339%3B%3B%2520%2520%2520%2520%2520%2520%7D)%3B%2520%2520%2520%2520%7D%2520on%2520PlatformException%2520catch%2520(e)%2520%7B%2520%2520%2520%2520%2520%2520setState(()%2520%7B%2520%2520%2520%2520%2520%2520%2520%2520_status%2520%3D%2520%26%2339%3BGot%2520error%3A%2520%24e%26%2339%3B%3B%2520%2520%2520%2520%2520%2520%7D)%3B%2520%2520%2520%2520%7D%2520%2520%7D%2520%2520%40override%2520%2520Widget%2520build(BuildContext%2520context)%2520%3D%26gt%3B%2520MaterialApp(%2520%2520%2520%2520%2520%2520%2520%2520home%3A%2520Scaffold(%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520appBar%3A%2520AppBar(%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520title%3A%2520const%2520Text(%26%2339%3BWeb%2520Auth%25202%2520example%26%2339%3B)%2C%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520)%2C%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520body%3A%2520Center(%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520child%3A%2520Column(%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520mainAxisAlignment%3A%2520MainAxisAlignment.center%2C%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520children%3A%2520%26lt%3BWidget%26gt%3B%5B%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520Text(%26%2339%3BStatus%3A%2520%24_status%5Cn%26%2339%3B)%2C%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520const%2520SizedBox(height%3A%252080)%2C%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520ElevatedButton(%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520onPressed%3A%2520()%2520async%2520%7B%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520await%2520authenticate()%3B%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%7D%2C%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520child%3A%2520const%2520Text(%26%2339%3BAuthenticate%26%2339%3B)%2C%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520)%2C%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%5D%2C%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520)%2C%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520)%2C%2520%2520%2520%2520%2520%2520%2520%2520)%2C%2520%2520%2520%2520%2520%2520)%3B%7D%253C%2Fcode">