• Stars
    star
    172
  • Rank 221,201 (Top 5 %)
  • Language
    Dart
  • License
    MIT License
  • Created over 5 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Flutter plugin for authenticating a user with a web service

Web Auth for Flutter

A Flutter plugin for authenticating a user with a web service, even if the web service is run by a third party. Most commonly used with OAuth2, but can be used with any web flow that can redirect to a custom scheme.

In the background, this plugin uses ASWebAuthenticationSession on iOS 12+ and macOS 10.15+, SFAuthenticationSession on iOS 11, Chrome Custom Tabs on Android and opens a new window on Web. You can build it with iOS 8+, but it is currently only supported by iOS 11 or higher.

iOS Android
iOS Android
macOS
macOS

Usage

To authenticate against your own custom site:

import 'package:flutter_web_auth/flutter_web_auth.dart';

// Present the dialog to the user
final result = await FlutterWebAuth.authenticate(url: "https://my-custom-app.com/connect", callbackUrlScheme: "my-custom-app");

// Extract token from resulting url
final token = Uri.parse(result).queryParameters['token']

To authenticate the user using Google's OAuth2:

import 'package:flutter_web_auth/flutter_web_auth.dart';

import 'dart:convert' show jsonDecode;
import 'package:http/http.dart' as http;

// App specific variables
final googleClientId = 'XXXXXXXXXXXX-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com';
final callbackUrlScheme = 'com.googleusercontent.apps.XXXXXXXXXXXX-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

// Construct the url
final url = Uri.https('accounts.google.com', '/o/oauth2/v2/auth', {
  'response_type': 'code',
  'client_id': googleClientId,
  'redirect_uri': '$callbackUrlScheme:/',
  'scope': 'email',
});

// Present the dialog to the user
final result = await FlutterWebAuth.authenticate(url: url.toString(), callbackUrlScheme: callbackUrlScheme);

// Extract code from resulting url
final code = Uri.parse(result).queryParameters['code'];

// Construct an Uri to Google's oauth2 endpoint
final url = Uri.https('www.googleapis.com', 'oauth2/v4/token');

// Use this code to get an access token
final response = await http.post(url, body: {
  'client_id': googleClientId,
  'redirect_uri': '$callbackUrlScheme:/',
  'grant_type': 'authorization_code',
  'code': code,
});

// Get the access token from the response
final accessToken = jsonDecode(response.body)['access_token'] as String;

Note: To use multiple scopes with Google, you need to encode them as a single string, separated by spaces. For example, scope: 'email https://www.googleapis.com/auth/userinfo.profile'. Here is a list of all supported scopes.

Setup

Setup works as for any Flutter plugin, expect the Android and Web caveats outlined below:

Android

In order to capture the callback url, the following activity needs to be added to your AndroidManifest.xml. Be sure to relpace YOUR_CALLBACK_URL_SCHEME_HERE with your actual callback url scheme.

<manifest>
  <application>

    <activity android:name="com.linusu.flutter_web_auth.CallbackActivity" android:exported="true">
      <intent-filter android:label="flutter_web_auth">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="YOUR_CALLBACK_URL_SCHEME_HERE" />
      </intent-filter>
    </activity>

  </application>
</manifest>

Web

On the Web platform an endpoint needs to be created that captures the callback URL and sends it to the application using the JavaScript postMessage() method. In the ./web folder of the project, create an HTML file with the name e.g. auth.html with content:

<!DOCTYPE html>
<title>Authentication complete</title>
<p>Authentication is complete. If this does not happen automatically, please
close the window.
<script>
  window.opener.postMessage({
    'flutter-web-auth': window.location.href
  }, window.location.origin);
  window.close();
</script>

Redirection URL passed to the authentication service must be the same as the URL on which the application is running (schema, host, port if necessary) and the path must point to created HTML file, /auth.html in this case. The callbackUrlScheme parameter of the authenticate() method does not take into account, so it is possible to use a schema for native platforms in the code.

For the Sign in with Apple in web_message response mode, postMessage from https://appleid.apple.com is also captured, and the authorization object is returned as a URL fragment encoded as a query string (for compatibility with other providers).

Troubleshooting

When you use this package for the first time, there are some problems you may have. These are some of the common solutions

Troubleshooting callbackUrlScheme

  • callbackUrlScheme must be a valid schema string or else this wont work.
  • A valid RFC 3986 URL scheme must consist of "a letter and followed by any combination of letters, digits, plus ("+"), period ("."), or hyphen ("-")."
  • scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
  • This means you can not use underscore "_", space " " or uppercase "ABCDEF...". You can not also start with a number. See RFC3986#page-17
  • examples of VALID callbackUrlScheme are callback-scheme, another.scheme, examplescheme
  • examples of INVALID callbackUrlScheme are callback_scheme,1another.scheme, exampleScheme

Troubleshooting Flutter App

  • You have to tell the FlutterWebAuth.authenticate function what your callbackUrlScheme is.

  • Example if your callbackUrlScheme is valid-callback-scheme, your dart code will look like

    import 'package:flutter_web_auth/flutter_web_auth.dart';
    
    // Present the dialog to the user
    final result = await FlutterWebAuth.authenticate(url: "https://my-custom-app.com/connect", callbackUrlScheme: "valid-callback-scheme");

Troubleshooting Android

  • You are required to update your AndroidManifest.xml to include the com.linusu.flutter_web_auth.CallbackActivity activity something like

    <manifest>
      <application>
    
        <!-- add the com.linusu.flutter_web_auth.CallbackActivity activity -->
        <activity android:name="com.linusu.flutter_web_auth.CallbackActivity" android:exported="true">
          <intent-filter android:label="flutter_web_auth">
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="YOUR_CALLBACK_URL_SCHEME_HERE" />
          </intent-filter>
        </activity>
    
      </application>
    </manifest>
  • Example of valid AndroidManifest.xml with VALID callbackUrlScheme. in the example below valid-callback-scheme is our callbackUrlScheme

    <manifest>
      <application>
    
        <activity android:name="com.linusu.flutter_web_auth.CallbackActivity" android:exported="true">
          <intent-filter android:label="flutter_web_auth">
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="valid-callback-scheme" />
          </intent-filter>
        </activity>
    
      </application>
    </manifest>
  • If you are targeting S+ (version 31 and above) you need to provide an explicit value for android:exported. If you followed earlier installation instructions this was not included. Make sure that you add android:exported="true" to the com.linusu.flutter_web_auth.CallbackActivity activity in your AndroidManifest.xml file.

    - <activity android:name="com.linusu.flutter_web_auth.CallbackActivity">
    + <activity android:name="com.linusu.flutter_web_auth.CallbackActivity" android:exported="true">

Troubleshooting OAuth redirects

  • Your OAuth Provider must redirect to the valid callbackUrlScheme + ://. This mean if your callbackUrlScheme is validscheme, your OAuth Provider must redirect to validscheme://
  • Example with php
    <?php
    
    header("Location: validscheme://?data1=value1&data2=value2");

Troubleshooting HTML redirects

  • If you are using HTML hyperlinks, it must be a valid callbackUrlScheme + ://. This mean if your callbackUrlScheme is customappname, your html hyperlink should be customappname://

  • example with HTML

    <a href="customappname://?data1=value1&data2=value2">Go Back to App</a>

Troubleshooting passing data to app

  • You can pass data back to your app by adding GET query parameters. This means by adding name=value type of data after your callbackUrlScheme + :// + ?

  • example to pass access-token to your app a valid url for that could be

    my-callback-schema://?access-token=jdu9292s
    
  • You can pass multipe data by concatenating with &

    my-callback-schema://?data1=value1&data2=value2
    
  • example to pass access-token and user_id to your app a valid url for that could be

    my-callback-schema://?access-token=jdu9292s&user_id=23
    
  • You can get the data in your app by using Uri.parse(result).queryParameters

    // Present the dialog to the user
    final result = await FlutterWebAuth.authenticate(url: "https://my-custom-app.com/connect", callbackUrlScheme: "valid-callback-scheme");
    // Extract token from resulting url
    String accessToken = Uri.parse(result).queryParameters['access-token'];
    String userId = Uri.parse(result).queryParameters['user_id'];

Cannot open keyboard on iOS

This seems to be a bug in ASWebAuthenticationSession, and no work around have been found. Please see issue #120 for more info.

Error on macOS if Chrome is default browser

This seems to be a bug in ASWebAuthenticationSession, and no work around have been found. Please see issue #136 for more info.

More Repositories

1

node-appdmg

๐Ÿ’พ Generate your app dmgs
JavaScript
1,678
star
2

Marionette

๐Ÿงธ Swift library which provides a high-level API to control a WKWebView
Swift
393
star
3

react-native-get-random-values

A small implementation of `getRandomValues` for React Native
JavaScript
272
star
4

wext-shipit

Automate the process of shipping Web Extensions for Chrome, Firefox, Safari, Opera and Edge
JavaScript
125
star
5

node-loudness

๐Ÿ”Š A node.js library to control the systems output volume
JavaScript
110
star
6

fanny-pack

๐Ÿ—„ Fanny Pack is a non-fancy, but very practical, key/value-store
TypeScript
107
star
7

JSBridge

๐Ÿ” Bridge your JavaScript library for usage in Swift
Swift
105
star
8

secure-remote-password

A modern SRP implementation for Node.js and Web Browsers
JavaScript
86
star
9

vscode-auto-dark-mode

Automatically switch between light and dark themes depending on the system dark mode toggle
JavaScript
79
star
10

scandium

๐Ÿš€ Easily deploy any Node.js web server to AWS Lambda
JavaScript
70
star
11

fs-xattr

๐Ÿ”– Node.js module for manipulating extended attributes
C
57
star
12

php-bitcoin-address-validator

๐Ÿ’ฐ A simple, easy to use PHP Bitcoin address validator
PHP
54
star
13

node-application-config

๐Ÿ”ง Store config for your node applications
JavaScript
45
star
14

emoji-commit

Rust
44
star
15

cwasm-nsgif

GIF decoding for Node.js, using Libnsgif compiled to WebAssembly
JavaScript
40
star
16

server-accepts-email

Check if an SMTP server accepts emails to a given address
TypeScript
39
star
17

cwasm-lodepng

PNG decoding for Node.js, using LodePNG compiled to WebAssembly
JavaScript
37
star
18

node-line-in

๐ŸŽค Capture audio with a simple stream interface
C++
34
star
19

pg-error-constants

PostgresQL error constants for use with Node.js
JavaScript
31
star
20

node-application-config-path

Store your application config in the right location.
JavaScript
28
star
21

swift-napi-bindings

C
27
star
22

node-cachedir

Get a directory for your caching needs
JavaScript
25
star
23

resize-image-data

Resize a decoded raw image
JavaScript
25
star
24

gitignore-to-dockerignore

Generate an equivalent `.dockerignore` file from an existing `.gitignore` file
JavaScript
24
star
25

node-jsonlines

Parse JSONLines with Node.js.
JavaScript
22
star
26

react-native-webcrypto

WebCrypto implementation for React Native
Java
22
star
27

node-ds-store

.DS_Store manipulation and creation from node.js
JavaScript
22
star
28

base32-encode

Base32 encoder with support for multiple variants
JavaScript
22
star
29

buffer-from

A ponyfill for Buffer.from
JavaScript
21
star
30

decode-ico

Decode `.ico` icons
JavaScript
20
star
31

RasterizeXCAssets

Rasterize svg files into your XCAssets
Swift
20
star
32

rust-raop-player

AirPlay player for the RAOP v2 protocol with synchronization
Rust
18
star
33

ts-readme-generator

Generate API documentation straight into the Readme file from TypeScript typings
JavaScript
18
star
34

stream-file-type

Get the file type by inspecting a stream
JavaScript
17
star
35

node-albatross

Best way to access MongoDB from Node.js
JavaScript
16
star
36

node-dark-mode-listener

A small library for listening to dark mode changes on macOS Mojave
JavaScript
16
star
37

ico-to-png

Convert an ICO file to a PNG file
JavaScript
16
star
38

flutter_maps

Native maps for Flutter, embedded as a native view using the PlatformView API
Kotlin
14
star
39

buffer-alloc-unsafe

A ponyfill for Buffer.allocUnsafe
JavaScript
13
star
40

swift-node-addon-examples

Swift
12
star
41

blockhash-core

Core implementation of the blockhash perceptual image hashing algorithm
JavaScript
12
star
42

rust-ansi-escapes

Ansi escape codes for Rust
Rust
11
star
43

cwasm-jpeg-turbo

JPEG decoding for Node.js, using libjpeg-turbo compiled to WebAssembly
Dockerfile
11
star
44

node-alias

Mac OS aliases creation and reading from node.js
JavaScript
11
star
45

buffer-alloc

A ponyfill for Buffer.alloc
JavaScript
11
star
46

buffer-fill

A ponyfill for Buffer.fill
JavaScript
9
star
47

base32-decode

Base32 decoder with support for multiple variants
JavaScript
9
star
48

hex-to-array-buffer

Turn a string of hexadecimal characters into an `ArrayBuffer`
JavaScript
9
star
49

node-parse-iso-duration

Parse an ISO 8601 duration to milliseconds
JavaScript
9
star
50

DarkModeListener

A small cli tool to listen to dark mode changes on macOS Mojave
Swift
9
star
51

gopher-hcl

The official HCL library, compiled to JavaScript with GopherJS
HCL
9
star
52

encode-utf8

Turn a string into an ArrayBuffer by using the UTF8 encoding
JavaScript
9
star
53

node-generate-rsa-keypair

Generate an RSA keypair
C
9
star
54

domain-name-regex

A regex to validate domain names
JavaScript
9
star
55

is-my-ip-valid

A small lib to validate IP addresses
JavaScript
8
star
56

node-capture-window

Capture a desktop window to a png file. Simple and easy.
Objective-C
8
star
57

utc-version

JavaScript
8
star
58

react-spacer

An element to repesent space between other elements, for use in flexbox layouts
JavaScript
8
star
59

raptor-rpc

Node.js library for creating RPC servers.
JavaScript
8
star
60

node-xorshift128plus

xorshift128+ implementation for Node.js
C++
8
star
61

flutter_jsbridge

Bridge your JavaScript library for usage in Flutter ๐Ÿš€
Swift
8
star
62

dhcp-spy

Silently listen for DHCP requests on the network
JavaScript
8
star
63

node-cstruct

Use C `struct`s in Javascript while keeping the syntax intact.
JavaScript
8
star
64

node-append-field

W3C HTML JSON form compliant field appender
JavaScript
7
star
65

cwasm-webp

WEBP decoding for Node.js, using libwebp compiled to WebAssembly
JavaScript
7
star
66

upload-opera-extension

Submit an update to a Opera Extension with one simple function call
JavaScript
7
star
67

parse-hostname

Parse a hostname into three parts: subdomain, domain and public suffix
JavaScript
7
star
68

react-stacked

Building blocks for robust cross-platform layouts
JavaScript
7
star
69

react-with-separator

Add a separator between each element
JavaScript
6
star
70

md5-dir

JavaScript
6
star
71

fast-base64-encode

A fast Base64 encoder with a low level API
JavaScript
6
star
72

array-buffer-to-hex

Turn an `ArrayBuffer` into a string of hexadecimal characters
JavaScript
6
star
73

ts-replace-all

String#replaceAll polyfill for TypeScript
JavaScript
6
star
74

swish-qrcode-svg

Generate Swish styled QR Code as SVG images
6
star
75

omega2-rust

This is a Docker image with an Omega2 Toolchain setup together with Rust
Dockerfile
6
star
76

node-print-diff

Prints a pretty diff of two strings
JavaScript
6
star
77

murmur-128

MurmurHash3 x86 128-bit implemented in JavaScript
JavaScript
5
star
78

ts-mutex

A very simple Mutex, with an easy to use API and excellent TypeScript typings
JavaScript
5
star
79

Soon

Example todo list application for iOS
Swift
5
star
80

is-my-date-valid

JavaScript
5
star
81

beer-recipes

5
star
82

format-email

Format emails according to RFC 5322
JavaScript
5
star
83

rust-alac-encoder

ALAC Encoder for Rust
Rust
4
star
84

node-wad

Manipulate rock raiders WAD files from nodejs
JavaScript
4
star
85

format-email-address

Format an email address before sending email to it
JavaScript
4
star
86

ts-unwrap

A simple `unwrap` function for use with TypeScript
JavaScript
4
star
87

flutter_biopass

Store a password behind biometric authentication
Dart
4
star
88

fs-temp

Temporary files and directories in Node.js
JavaScript
4
star
89

wext-manifest

Web Extensions polyfill for the `manifest.json` API
JavaScript
4
star
90

expo-legacy-browser-support

iOS 9 and IE 11 support for Expo Web
JavaScript
4
star
91

webmail-api

A unified API to different webmail providers
JavaScript
4
star
92

ts-resource-pool

An easy to use resource pool, including support for recycling resources, with excellent TypeScript typings
JavaScript
3
star
93

decode-bmp

Decode `.bmp` images
JavaScript
3
star
94

p-sleep

Promisified sleep function
JavaScript
3
star
95

rustic-yellow

Rust
3
star
96

file-to-array-buffer

Turn a File (or any Blob) into an ArrayBuffer
JavaScript
3
star
97

murmur-32

MurmurHash3 x86 32-bit implemented in JavaScript
JavaScript
3
star
98

rust-log-update

Log by overwriting the previous output in the terminal
Rust
3
star
99

marionettejs

Node.js bindings for Marionette, a high-level API to control a WKWebView
Swift
3
star
100

ts-unreachable

Utility function for exhaustiveness checking with TypeScript
JavaScript
3
star