Flutter plugin for authenticating a user with a web service

Overview

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'];

// Use this code to get an access token
final response = await http.post('https://www.googleapis.com/oauth2/v4/token', 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;

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" >
      <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:

>
<title>Authentication completetitle>
<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).

Comments
  • PlatformException(CANCELED, User canceled login, null) on Android

    PlatformException(CANCELED, User canceled login, null) on Android

    Hi, This is my first time using Oauth2 and I am trying to get my callback from the salesforce rest API. I can launch the authenticate() and login to salesforce. Salesforce then re-routes to my call back "myappname://callback?code=aWekysIEeq.....etc", but it throws a PlatformException(CANCELED, User canceled login, null) on android. I check out issue #45 but I am already calling things the right way as far as I can tell. (I might be overlooking the obvious)

    I have included the image of the code I am using. (censored both my client_id and redirect_uri "myappname") Capture1

    Also, I have my android manifest "intent-filter" inside my main activity. Capture2

    If anyone has any ideas or knows of anything I can try I would greatly appreciate it.

    thanks!

    help wanted 
    opened by jerejacobson 14
  • Fix history save flag issues

    Fix history save flag issues

    This adds an extra optional parameter to the authenticate method to specify whether the history should be saved, so 2FA is still compatible, but at the same time, the custom tabs can be closed for those without 2FA. Fixes #37 for those without 2FA.

    Edit: I barely coded Kotlin before, so I don't know if my Kotlin code style is okay. I am pretty sure, some of Kotlin's null-check-operators can be used to make the code prettier. If you know how to do this, tell me and I will add another commit to this PR to fix the code style. Also: As you can see, this change doesn't change the default behavior, but only adds new behavior, so all applications will still be fully compatible after merging this bugfix/feature.

    opened by ThexXTURBOXx 12
  • Flutter 3 changes

    Flutter 3 changes

    Flutters API for widget binding changed and we need probably a small update to prevent a failed build. Should probably be the same error for all platforms.

    image
    opened by Sesa1988 11
  • Flutter Web is not supported

    Flutter Web is not supported

    Hello, As you have mentioned in your plugin that web is supported but when I tried using the login in the web it is not working at all, kindly let me know is there any special steps which I need to follow to make it work on the web ?

    help wanted good first issue 
    opened by crimsonsuv 10
  • authenticate method never complete if cancelled on Android

    authenticate method never complete if cancelled on Android

    Hi,

    I found some problem when closing the tab before authentication completed. My expect behaviour is it will throw an error from FlutterWebAuth.authenticate but on Android it didn't

    My code is

    final result = await FlutterWebAuth.authenticate(
          url: 'http://something?redirect_uri=myapp://authen',
          callbackUrlScheme: 'myapp',
        );
    final code = Uri.parse(result).queryParameters['code'];
    

    I debugged final code line but it will never reach there, also it don't throw any error

    On iOS, it doesn't have same issue. When I'm closing the web tab I would get a PlatformException(EUNKNOWN, The operation couldnโ€™t be completed. (com.apple.AuthenticationServices.WebAuthenticationSession error 1.), null)} } and can just use try-catch to handle it

    And somehow it create an issue with my flutter_bloc's bloc, after tab was closed flutter_bloc's stream stop taking any event. I've got no idea how it can relate but here I would want to capture that cancelling tab because if I do I think I won't have that problem because on iOS it works perfectly

    help wanted 
    opened by izht 10
  • ๐ŸŽ‰ Add Web support

    ๐ŸŽ‰ Add Web support

    This PR adds support for Web platform as discussed in #16. The authentication service will open in a new browser window. To capture callback URL you need to create an HTML file with JavaScript postMessage() method which sends URL to the application. It is explained with an example in README.md.

    opened by czepiec 9
  • Web auth shows two options to the user, app name and flutter_web_auth

    Web auth shows two options to the user, app name and flutter_web_auth

    My app supports deep links and also uses this package for web auth. there is a confusing action sheet shown to the user before opening the browser:

    screenshot

    This is my intent:

    <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="myappscheme" />
               </intent-filter>
           </activity>
    

    Is there any way to open the browser right away instead of showing this confusing UI?

    opened by maysamsh 8
  • No redirection once logged in with Google

    No redirection once logged in with Google

    Hello, I am trying to follow the sample given in the doc to use Oauth2 in Android with Google as provider. I am well redirected to Google authentication page. But once I log in, I have no redirection at all (neither to the app nor in the browser). Also, I tried to open Chrome and access the redirect_uri manually but it responds the DNS_PROBE_FINISHED_NXDOMAIN error.

    Relevant code:

    final googleClientId = 'XXXXXXX-xxxxxxxxxxxx.apps.googleusercontent.com';
    final callbackUrlScheme = 'com.googleusercontent.apps.XXXXXXX-xxxxxxxxxxxx';
    
        final url = Uri.https('accounts.google.com', '/o/oauth2/v2/auth', {
          'response_type': 'code',
          'client_id': googleClientId,
          'redirect_uri': '$callbackUrlScheme:/',
          'scope': 'email',
        });
    
    final result = await FlutterWebAuth.authenticate(url: url.toString(), callbackUrlScheme: callbackUrlScheme);
    

    Relevant activity:

    <activity android:name="com.linusu.flutter_web_auth.CallbackActivity" >
                <intent-filter>
                    <action android:name="android.intent.action.VIEW" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <category android:name="android.intent.category.BROWSABLE" />
                    <data android:scheme="com.googleusercontent.apps.XXXXXXX-xxxxxxxxxxxx"/>
                </intent-filter>
            </activity>
    

    Am I missing something? Or does that mean I misconfigured my app on Google side? Any help would be appreciated!

    opened by Rhesos 8
  • Logging out

    Logging out

    I have been trying to logout of the session using the logout endpoint.

    I suppose when dealing with these flows they're all standardized no matter who the auth server provider is right?

    What's the correct way to logout?

    With the auth server I'm using, Okta, it says the following:

    Note: When making requests to the /logout endpoint, the browser (user agent) should be redirected to the endpoint. You can't use AJAX with this endpoint.
    

    I can construct the logout url just fine, but it just sends me to a 400 erro okta page.

    This is the documentation: https://developer.okta.com/docs/reference/api/oidc/#logout

    Any ideas?

    Thanks.

    opened by RaulMarquezInclan 7
  • fatal error: module 'flutter_web_auth' not found

    fatal error: module 'flutter_web_auth' not found

    When running the project on a simulator everything seems to work fine. Once i tried to deploy to an actual device I get the following error:

    iOS Version - 13.0

    Xcode Version - 11.3.1

    Flutter Version - 1.12.13+hotfix.8

    Building AOT snapshot in release mode (ios-release)...
    Building App.framework for arm64...

    Building App.framework for armv7...
    Building AOT snapshot in release mode (ios-release)...             30.5s
    Built to build/aot/.
    warning: parsing line table prologue at offset 0x6f697463 found unsupported
    version 0x00
    warning: line table parameters mismatch. Cannot emit.
    note: while processing
    /Users/<Username>/Documents/flutter_test_app/build/aot/armv7/snapsho
    t_assembly.o
    Project /Users/<Username>/Documents/flutter_test_app built and
    packaged successfully.
    /Users/<Username>/Documents/flutter_test_app/ios/Runner/GeneratedPlu
    ginRegistrant.m:10:9: fatal error: module 'flutter_web_auth' not found
    @import flutter_web_auth;
     ~~~~~~~^~~~~~~~~~~~~~~~
    1 error generated.
    /Users/<Username>/Documents/flutter_test_app/ios/Runner/GeneratedPlu
    ginRegistrant.m:10:9: fatal error: module 'flutter_web_auth' not found
    @import flutter_web_auth;
     ~~~~~~~^~~~~~~~~~~~~~~~
    1 error generated.
    note: Using new build system
    note: Planning build
    note: Constructing build description
    

    Could not build the precompiled application for the device.

    Error running application on iPhone.

    opened by JoellyR 6
  • Option to send headers to the

    Option to send headers to the "web view"

    Would it be possible to add an option in the library to add headers to the request?

    For example on Android:

    intent.intent.putExtra(Browser.EXTRA_HEADERS, Bundle().apply { putString(headerName, headerValue) })

    opened by akvus 6
  • [PROPOSAL] debug flag

    [PROPOSAL] debug flag

    debug flag - used for avoid comparing Url.base.originand messageEvent.origin that gives us opportunity to test without deploy (ex. deployed back example.com and local flutter app localhost)

    opened by Doldrums 1
  • Instead of Chrome Custom Tabs is Samsung Custom Tabs

    Instead of Chrome Custom Tabs is Samsung Custom Tabs

    Hello,

    Thank you for your work!

    If several custom tabs are installed, the first one is used.

    Can you add the package name parameter to force a particular custom tabs.

    Thanks

    opened by mohachouch 0
  • Browser remembers my credentials, so I have to clear browser cache

    Browser remembers my credentials, so I have to clear browser cache

    Hi, I have a problem with login in Android. When I login 2nd time and after, I automatically pass on without login/password prompt, so if I want to change user, I have to run Chrome browser from Android desktop and choose Clear browsing data from its Settings. I know there is preferEphemeral flag, but it works only in iOS.

    opened by adminant 5
  • Issue prompting for authentication on OSX with Chrome as default browser

    Issue prompting for authentication on OSX with Chrome as default browser

    Issue Description

    When using flutter_web_auth v0.4.1 on Darwin OSX (12.5.1) targets that have the default browser set to Chrome (Version 105.0.5195.102 (Official Build) (x86_64)), the authentication prompt opens and closes immediately afterwards, causing a PlatformException. If the default browser is set to Safari, the authentication flows work as expected.

    Steps to reproduce

    1. Set Chrome as default browser in OSX
    2. Start the authentication flow with the default browser (Chrome), using flutter_web_auth v0.4.1
    3. See the chrome window open and immediately close
    4. Stack trace:
    [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: PlatformException(EUNKNOWN, The operation couldnโ€™t be completed. (com.apple.AuthenticationServices.WebAuthenticationSession error 3.), null, null)
    #0      StandardMethodCodec.decodeEnvelope
    package:flutter/โ€ฆ/services/message_codecs.dart:653
    #1      MethodChannel._invokeMethod
    package:flutter/โ€ฆ/services/platform_channel.dart:296
    <asynchronous suspension>
    #2      FlutterWebAuth.authenticate
    package:flutter_web_auth/flutter_web_auth.dart:35
    <asynchronous suspension>
    
    opened by Jack64 1
  • iOS Authentication works in 0.4.0, but not in 0.4.1 - AQUIRE_ROOT_VIEW_CONTROLLER_FAILED

    iOS Authentication works in 0.4.0, but not in 0.4.1 - AQUIRE_ROOT_VIEW_CONTROLLER_FAILED

    I have an example app which authenticates with multiple identity providers, including Auth0 and Okta. Using 0.4.0, both buttons work on Android and iOS, but using 0.4.1, one button always results in an AQUIRE_ROOT_VIEW_CONTROLLER_FAILED error on iOS. For now, I will use 0.4.0, but I'm concerned I won't be able to update in the future.

    As I understand it, the change was to support Flutter apps with "add to app" use cases, but I think this may have broken for "pure" Flutter apps. I'm having trouble debugging the plugin, but I wonder if it should check for UIApplication.shared.delegate?.window??.rootViewController as? FlutterViewController first, and then check for UIApplication.shared.keyWindow?.rootViewController.

    opened by Will5 2
Releases(0.5.0)
Owner
Linus Unnebรคck
Linus Unnebรคck
Home-Service-App - Home Service App Built With Flutter

Home-Service-App Home Service App Sample Images

Justin Roy 2 Sep 4, 2022
Our application, MyArmyPal serves to be an all in one service for our service men.

Our application, MyArmyPal serves to be an all in one service for our service men. It seeks to provide convenience and useful features just one tap away. Its main features include an IPPT Calculator, reservist checklist, customized IPPT training plan according to the user's current fitness level and a canteen order pick up service in all army camps. We are also implementing an anytime Eliss system using computer vision for users to check on their push up form easily.

Poh Wei Pin 3 Jun 17, 2022
Flutter widget library containing buttons for authenticating with popular social networks: Apple, Google, Facebook, Twitter and Microsoft.

Flutter Auth Buttons This library is now in maintenance mode I'm no longer actively using Flutter and don't have the time to keep this library maintai

Duncan Jones 115 Nov 3, 2022
A Flutter step_tracker plugin is collect information from user and display progress through a sequence of steps. this plugin also have privilege for fully customization from user side. like flipkart, amazon, myntra, meesho.

step_tracker plugin A Flutter step_tracker plugin is collect information from user and display progress through a sequence of steps. this plugin also

Roshan nahak 5 Oct 21, 2022
Flutter plugin for interacting with Accessibility Service in Android.

flutter_accessibility_service a plugin for interacting with Accessibility Service in Android. Accessibility services are intended to assist users with

Iheb Briki 10 Dec 22, 2022
Create a Flutter User Profile Page UI where you can access and edit your user's information within your Flutter app.

Flutter Tutorial - User Profile Page UI 1/2 Create a Flutter User Profile Page UI where you can access and edit your user's information within your Fl

Johannes Milke 46 Dec 6, 2022
Create a Flutter User Profile Page UI where you can access and edit your user's information within your Flutter app.

Flutter Tutorial - User Profile Page UI #2 Create a Flutter User Profile Page UI where you can access and edit your user's information within your Flu

Johannes Milke 45 Dec 15, 2022
Let's create a complete Flutter User Profile Page with SharedPreferences to persist the user's information in Flutter.

Flutter Tutorial - User Profile & SharedPreferences Let's create a complete Flutter User Profile Page with SharedPreferences to persist the user's inf

Johannes Milke 21 Dec 3, 2022
User auth form - Signup and signin user auth form with ability to stay signed in and have an option to signout.

user_auth_form SIgnup and signin user authentification form Getting Started This project is a starting point for a Flutter application. A few resource

null 0 Jan 6, 2022
Yumniastic is a online food delivery service app built with Flutter and Django

Welcome to Flutter Yumniastic ?? Yumniastic is a online food delivery service app built with Flutter and Django ?? See Screenshots See ScreenShots Dow

null 21 Dec 26, 2022
Flutter Wallpaper service app

Walls Your phone wallpaper is great way to express your unique personality. Walls is a wallpaper service app with out any Ads. check this blog post Be

Naveen Jujaray 25 Dec 16, 2022
MVC pattern for flutter. Works as state management, dependency injection and service locator.

MVC pattern for flutter. Works as state management, dependency injection and service locator. Model View Controller Here's a diagram describing the fl

xamantra 115 Dec 12, 2022
This is an example project for the article about implementing clean architecture in flutter with riverpod and supabase as backend service.

The Example This is an example how to implement clean architecture with domain driven design and riverpod in flutter projects. Getting Started Rename

Volodymyr Hodiak 45 Dec 30, 2022
Push Notification service for anime episodes and news. The episode updates will be based on actual upload on the internet and NOT Japan tv schedule as other apps do.

Quantz Push Notification service for anime episodes and news. Features Sub and dub - get notified with latest anime episodes on the internet. Ongoing

null 18 Nov 21, 2022
A demo Project Showcasing HowTo use GraphQL to conect as a client to a GraphQL service.

graphql_demoapp A Flutter App to demonstrate how to work with GraphQL Server, connecting through our app as a client. Working with basic queries and m

Igor L Sambo 2 Nov 7, 2021
An open source food delivery product and service that will be developed on the FilledStacks YouTube channel

Box't Out An open source food delivery product and service that will be developed on the FilledStacks YouTube channel. The repo will contain all the s

Dane Mackier 379 Jan 7, 2023
This project is Riot game information check service using Riot api.

riot_api_project this project is Riot game information check service using Riot api. Getting Started This project is a starting point for a Flutter ap

null 1 Dec 12, 2021
Get It - Simple direct Service Locator that allows to decouple the interface from a concrete implementation and to access the concrete implementation from everywhere in your App. Maintainer: @escamoteur

โค๏ธ Sponsor get_it This is a simple Service Locator for Dart and Flutter projects with some additional goodies highly inspired by Splat. It can be used

Flutter Community 1k Jan 1, 2023