The Simplest way to Authenticate in Flutter

Overview

Simple Auth Pub Most apps need to make API calls. Every API needs authentication, yet no developer wants to deal with authentication. Simple Auth embeds authentication into the API so you dont need to deal with it.

This is a port of Clancey.SimpleAuth for Dart and Flutter

The network/api part including the generator was based off of Chopper by Hadrien Lejard

Join the chat at https://gitter.im/simple_auth/community

iOS: Build status

Android: Build status

Providers

Current Built in Providers

  • Azure Active Directory
  • Amazon
  • Dropbox
  • Facebook
  • Github
  • Google
  • Instagram
  • Linked In
  • Microsoft Live Connect
  • Keycloak
  • And of course any standard OAuth2/Basic Auth server.

Usage

var api = new simpleAuth.GoogleApi(
      "google", "client_id",clientSecret: "clientSecret",
      scopes: [
        "https://www.googleapis.com/auth/userinfo.email",
        "https://www.googleapis.com/auth/userinfo.profile"
      ]);
var request = new Request(HttpMethod.Get, "https://www.googleapis.com/oauth2/v1/userinfo?alt=json");
var userInfo = await api.send<UserInfo>(request);

That's it! If the user is not logged in, they will automatically be prompted. If their credentials are cached from a previous session, the api call proceeds! Expired tokens even automatically refresh.

Flutter Setup

Call SimpleAuthFlutter.init(); in your Main.Dart. Now Simple Auth can automatically present your login UI

Redirect

Google requires the following redirect: com.googleusercontent.apps.YOUR_CLIENT_ID

Simple Auth by default uses SFSafari on iOS and Chrome Tabs on Android.

This means normal http redirects cannot work. You will need to register a custom scheme for your app as a redirect. For most providers, you can create whatever you want. i.e. com.myapp.foo:/redirct

Android Manifest

you would then add the following to your Android manifest

<activity android:name="clancey.simpleauth.simpleauthflutter.SimpleAuthCallbackActivity" >
    <intent-filter android:label="simple_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="com.myapp.foo" />
    </intent-filter>
</activity>

For instagram, the above won't work, as it will only accept redirect URIs that start with https. Add the following instead:

    <activity android:name="clancey.simpleauth.simpleauthflutter.SimpleAuthCallbackActivity">

      <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="http" />
        <data android:scheme="https" />
        <data android:host="myflutterapp.com" />
      </intent-filter>
    </activity>

iOS & macOS

on iOS you need something like the following as your AppDelegate.m file under the Runner folder

#include "AppDelegate.h"
#include "GeneratedPluginRegistrant.h"
#import <Flutter/Flutter.h>
#import <simple_auth_flutter/SimpleAuthFlutterPlugin.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [GeneratedPluginRegistrant registerWithRegistry:self];
  // Override point for customization after application launch.
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options{
    return [SimpleAuthFlutterPlugin checkUrl:url];
}

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
    return [SimpleAuthFlutterPlugin checkUrl:url];
}

@end

On macOS:

import Cocoa
import FlutterMacOS
import simple_auth_flutter

@NSApplicationMain
class AppDelegate: FlutterAppDelegate {
  override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
    return true
  }
    
    override func applicationDidFinishLaunching(_ notification: Notification) {
        let appleEventManager:NSAppleEventManager = NSAppleEventManager.shared()
        appleEventManager.setEventHandler(self, andSelector: #selector(AppDelegate.handleGetURLEvent(event:replyEvent:)), forEventClass: AEEventClass(kInternetEventClass), andEventID: AEEventID(kAEGetURL))

    }
    
    @objc func handleGetURLEvent(event: NSAppleEventDescriptor, replyEvent: NSAppleEventDescriptor) {
        let urlString = event.paramDescriptor(forKeyword: AEKeyword(keyDirectObject))?.stringValue!
        let url = URL(string: urlString!)!
        SimpleAuthFlutterPlugin.check(url);
    }
}

For iOS 11/macOS 10.15 and higher, you don't need to do anything else. On older versions the following is required in the info.plist

	<key>CFBundleURLTypes</key>
	<array>
		<dict>
			<key>CFBundleURLSchemes</key>
			<array>
				<string>com.myapp.foo</string>
			</array>
			<key>CFBundleURLName</key>
			<string>myappredirect</string>
		</dict>
	</array>

Note, if you want to avoid Apples mandatory user consent dialog

"foo" Wants to use "bar.com" to Sign In
This allows the app and website to share information about you.

add the lines above and set FooAuthenticator.useSSO = false; which will not use SFAuthenticationSession on iOS, and ASWebAuthenticationSession on macOS. This is the default behavior for the Keycloak provider.

Serialization

Json objects will automatically serialize if you conform to JsonSerializable

If you use the generator and you objects have the factory factory JsonSerializable.fromJson(Map<String, dynamic> json) your api calls will automatically Serialize/Deserialize

Or you can pass your own Converter to the api and handle conversion yourself.

Generator

Dart

pub run build_runner build

flutter

flutter packages pub run build_runner build

Add the following to your pubspec.yaml

dev_dependencies:
  simple_auth_generator:
  build_runner: ^0.8.0

The Generator is not required, however it will make things magical.

@GoogleApiDeclaration("GoogleTestApi","client_id",clientSecret: "client_secret", scopes: ["TestScope", "Scope2"])
abstract class GoogleTestDefinition {
  @Get(url: "https://www.googleapis.com/oauth2/v1/userinfo?alt=json")
  Future<Response<GoogleUser>> getCurrentUserInfo();
}

will generate a new Api for you that is easy to use!

var api = new GoogleTestApi("google");
var user = await api.getCurrentUserInfo();

For more examples, check out the example project

Contributor

TODO

  • Add more documentation
  • Add native flutter providers for google
Comments
  • googleApi.getUserProfile(), Invalid argument(s): The source must not be null

    googleApi.getUserProfile(), Invalid argument(s): The source must not be null

    i no longer get the error about int with the example project's google api key, but with my own google api key, i am still getting the error reported here: https://github.com/Clancey/simple_auth/issues/15#issue-356986288

    Invalid argument(s): The source must not be null

    that error is caught in this try:

    try {
                    var user = await googleApi.getUserProfile();
                    showMessage("${user.name} logged in");
                  } catch (e) {
                    showError(e);
                  }
    

    it fails with that before reaching the showMessage call, so it must be a problem somewhere in getUserProfile. what could i be missing with my google project?

    image

    image

    opened by matthewkooshad 23
  • how to resolve with the latest 2.1.0-dev version of dart sdk?

    how to resolve with the latest 2.1.0-dev version of dart sdk?

    The current Dart SDK version is 2.1.0-dev.0.0.flutter-be6309690f. Because every version of flutter_test from sdk depends on analyzer 0.32.4 and simple_auth_generator >=1.0.0 depends on analyzer ^0.31.2-alpha.2, flutter_test from sdk is incompatible with simple_auth_generator >=1.0.0. And because simple_auth_generator <1.0.0 requires SDK version >=2.0.0-dev <2.0.0, flutter_test from sdk is incompatible with simple_auth_generator. So, because app1 depends on both simple_auth_generator any and flutter_test any from sdk, version solving failed. pub get failed (1)

    opened by matthewkooshad 23
  • Azure login

    Azure login

    I'm trying the example you have online, so far I've made it log into my company but at the end I get a white screen login live

    This is my code static String azureClientId = "caa16c9f-xxxxx; static String azureTennant = "e50ebc8xxxxxxxxxx"; final simpleAuth.AzureADApi azureApi = new simpleAuth.AzureADApi( "azure", azureClientId, "https://login.microsoftonline.com/$azureTennant/oauth2/authorize", "https://login.microsoftonline.com/$azureTennant/oauth2/token", "https://login.microsoftonline.com/$azureTennant/oauth2/authorize?response_type=id_token&client_id=$azureClientId", "https://login.live.com/oauth20_desktop.srf" // "https://login.microsoftonline.com/common/oauth2/nativeclient" );

    Am I missing something?

    opened by osorito 16
  • Instance of 'CancelledException'

    Instance of 'CancelledException'

    version: 1.0.0+1
    
    environment:
      sdk: ">=2.0.0-dev.68.0 <3.0.0"
    
    dependencies:
      flutter:
        sdk: flutter
      
      cupertino_icons: ^0.1.2
      flutter_svg: ^0.7.0+1
      simple_auth_flutter: ^2.0.0
    

    Error Log-in with GoogleApi on Flutter Android I'm redirected to the browser, I log into my account but I do not go back to the app anymore and I get an error Instance of 'CancelledException' and Instance of 'Response<"String">'

    opened by breitembach 14
  • GitHub has the Amazon links for tokenUrl and authorizationUrl and also uses localhost for redirectUrl

    GitHub has the Amazon links for tokenUrl and authorizationUrl and also uses localhost for redirectUrl

    this.tokenUrl = "https://api.amazon.com/auth/o2/token"; this.authorizationUrl = "https://www.amazon.com/ap/oa";

    String redirectUrl = "http://localhost",

    opened by GroovinChip 13
  • azure ouauth failure

    azure ouauth failure

    If i tap login for azure, after adding the tennant id and the client id, the application gives this error.

    flutter run -d 5830DC35-D7AA-496D-8971-F0F1D3A1CF4D Launching lib/main.dart on iPhone X in debug mode... Running Xcode build...
    ├─Assembling Flutter resources... 2.4s └─Compiling, linking and signing... 2.8s Xcode build done. 6.7s Registered SimpleAuth on iOS Syncing files to device iPhone X...
    3,830ms (!)

    🔥 To hot reload changes while running, press "r". To hot restart (and rebuild state), press "R". An Observatory debugger and profiler on iPhone X is available at: http://127.0.0.1:62227/ For a more detailed help message, press "h". To detach, press "d"; to quit, press "q". flutter: FormatException: Unexpected end of input (at character 1)

    ^ Authenticator created presenting the authenticator *** First throw call stack: ( 0 CoreFoundation 0x000000010d9766fb __exceptionPreprocess + 331 1 libobjc.A.dylib 0x000000010cf1aac5 objc_exception_throw + 48 2 CoreFoundation 0x000000010d8c4ddc _CFThrowFormattedException + 194 3 CoreFoundation 0x000000010d9e59b4 -[__NSDictionaryM setObject:forKey:] + 1012 4 Runner 0x000000010a7e8414 __46+[SFSafariAuthenticator presentAuthenticator:]_block_invoke + 292 5 libdispatch.dylib 0x000000011082eccf _dispatch_call_block_and_release + 12 6 libdispatch.dylib 0x000000011082fd02 _dispatch_client_callout + 8 7 libdispatch.dylib 0x000000011083ba50 _dispatch_main_queue_callback_4CF + 1276 8 CoreFoundation 0x0000000<…> Lost connection to device.

    opened by osorito 11
  • Exception - AzureAd and the scope attribute.

    Exception - AzureAd and the scope attribute.

    I need to pass some scopes to the Azure auth service to get access to a bunch of services. But if I pass anything else than "openid" as scope I get the following error message from the plugin.

    "Exception: Unable to get an AuthToken from the server"

    I have tried to send the same request with postman and that request works just fine.

    opened by akeblom 11
  • Question about the callback activity

    Question about the callback activity

    <activity android:name="clancey.simpleauth.simpleauthflutter.SimpleAuthCallbackActivity" >
                <intent-filter android:label="simple_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="com.googleusercontent.apps.992461286651-k3tsbcreniknqptanrugsetiimt0lkvo" />
                </intent-filter>
            </activity>
    

    Is this what will take the user back to the app once they've authenticated? I'm trying to make my ap deep-linked so that when a user authorizes the app to connect to their GitHub account they get returned to the app rather than stay in the browser.

    opened by GroovinChip 11
  • FormatException error

    FormatException error

    I'm having an issue with the response after I'm authenticated. It looks like it is returning exactly what I need, but I'm guessing it's expecting a JSON object instead whatever this is. This is the exception I keep getting

    FormatException: Unexpected character (at character 1) access_token={accessToken}&expires_in=28800 ^ {accessToken} shows the actual token. I just replaced it for the sake of posting it here. My redirect url is good. I'm using the same configuration in another project in Xamarin with the same URLScheme on iOS. It works on the project, but obviously not here. Is there something I'm missing? Let me know what you need from me. Thanks.

    opened by ChizuNoYama 10
  • googleApi: determine Logged In without going through Login process when user is not Logged In

    googleApi: determine Logged In without going through Login process when user is not Logged In

    Login, then call login again. It will not present the UI. If tokens are cached and are valid, the UI will not be presented until the credentials are expired

    the problem about the above is that before the initial "Login" @Clancey said to do (24),, how can i check if the user has Logged in (without sending the user to go Login)? i only want to send the user to the Login page to Login if they are not Logged in. thanks!

    opened by matthewkooshad 10
  • App seems to not getUserProfile

    App seems to not getUserProfile

    I am following the examle in "simple_auth_flutter_example"

    When I get to

    var user = await googleApi.getUserProfile(); The app shows the Google Sign-in page.
    After 'signing' in nothing seems to happen. I have a breakpoint after the getUserProfile. It does not get hit.

    Sam

    opened by samgithub-duplicate 9
  • After Instagram Login redirect to webview

    After Instagram Login redirect to webview

    Hello, after login completed in Instagram redirect to webview (url is same of settings redirect url in Instagram App Developer). How to resolve this? In Android is good!

    opened by fabioselau077 0
  • Can I use this library in a Flutter app for web only ?

    Can I use this library in a Flutter app for web only ?

    Hi,

    Is it possible to use this simple_auth_flutter with a Flutter project for web only (so no android or io support) ??

    I have been trying to use this library in my app but I get the "MissingPluginException was thrown while activating platform stream on channel simple_auth_flutter/urlChanged". Since I dont have Android folders, I dont have MainActivity or build.gradles to update.

    opened by DanGM321 0
  • Custom tabs closes when putting the app on background or switching task

    Custom tabs closes when putting the app on background or switching task

    This has been an issue when using a 2FA. I figured out the fix would be removing the Intent.FLAG_ACTIVITY_NO_HISTORY in the CustomTabsAuthenticator.java

    opened by zpenguin52 2
  • [Fix] exported in Android 12

    [Fix] exported in Android 12

    For people with problems still using Flutter, in addition to putting exported=true in the application's <activity, you need to put it in the <activity of the installed plugins. That's the only way to work. It will look like this: <activity android:name="clancey.simpleauth.simpleauthflutter.SimpleAuthCallbackActivity" android:exported="true">

    opened by fabioselau077 0
Owner
James Clancey
discord: https://discord.gg/7Ms7ptM
James Clancey
A Flutter plugin for allowing users to authenticate with native Android & iOS Facebook login SDKs.

flutter_facebook_login A Flutter plugin for using the native Facebook Login SDKs on Android and iOS. AndroidX support if you want to avoid AndroidX, u

Iiro Krankka 404 Nov 26, 2022
Flutter Password Validator package helps you to validate user-entered passwords in your flutter app.

Flutter Password Validator Flutter Password Validator package helps you to validate sign-in user-entered passwords with your rules.

Aref Mozafari 26 Dec 14, 2022
Email and Password Authentication In Flutter & Firebase in Flutter 2.2

email_password_flutter_firebase Email and Password Authentication In Flutter & Firebase in Flutter 2.2 Overview This email and password authentication

null 0 Mar 24, 2022
Flutter Plugin for Sign In with Apple

Apple Sign In - Flutter Plugin Access Sign In with Apple from Flutter. Platform support This plugin currently only supports iOS. There's a JavaScript

Tom Gilder 156 Dec 28, 2022
A Flutter OAuth package for performing user authentication for your apps.

Flutter OAuth A Flutter OAuth package for performing user authentication for your apps. I've tested this with a small collection of APIs (Buffer, Stra

Joe Birch 173 Dec 9, 2022
A Flutter wrapper for AppAuth iOS and Android SDKs

flutter_appauth A Flutter plugin that provides a wrapper for native AppAuth SDKs (https://appauth.io) used authenticating and authorizing users. The r

Michael Bui 230 Dec 21, 2022
An OAuth authentication system built in Flutter using Google OAuth.

An OAuth authentication system built in Flutter using Google OAuth.

Kaushal 0 Sep 20, 2021
Flutter implementation of the Quickstart Supabase User Management app.

Supabase Flutter User Management This repo is a quick sample of how you can get started building apps using Flutter and Supabase. You can find a step

Supabase Community 56 Nov 14, 2022
This project is an example of Firebase authentication in a flutter

This project is an example of Firebase authentication in a flutter. This project shows how to implement a full authentication flow in Flutter, using sign Up with email and password, sign in with email and password, and reset password.

Nittin 4 Mar 11, 2022
A Flutter package that implements Google Sign In in pure Dart.

A Flutter package that implements Google Sign In in pure Dart. This package is compatible with google_sign_in plugin and works on all platforms Flutter supports but it's intended to be mainly used on Desktop.

Razvan Lung 10 Oct 26, 2022
WebView OAuth flows for desktop flutter apps

desktop_webview_auth A new flutter plugin project. Getting Started This project is a starting point for a Flutter plug-in package, a specialized packa

Invertase 22 Dec 17, 2022
Easy third party authentication (OAuth 2.0) for Flutter apps.

visa This is an OAuth 2.0 package that makes it super easy to add third party authentication to flutter apps. It has support for FB, Google, LinkedIn,

Emmanuel Olaojo 135 Dec 23, 2022
Authentication pages I made with Flutter and Firebase

Auth-with-Flutter-and-Firebase Authentication pages I made with Flutter and Firebase Overview This email and password authentication is implemented wi

Said Mirzayev 3 Jul 24, 2022
An example of JWT authentication with flutter.

flutter-jwt-auth-template An example of JWT authentication with flutter. Getting Started Clone this repository, and inside its folder, run: flutter pu

Enzo Di Tizio 23 Jan 4, 2023
In this Application Built Using Flutter🎯 along with FireBase 🔥for Managing the data

In this Application Built Using Flutter?? along with FireBase ??for Managing the data, I have Curated a simple?? Login/Sign Up Space along with Authentication!

Aashvi Kothari 4 Oct 9, 2022
The Simplest way to Authenticate and make Rest API calls in .Net

Simple Auth Every API needs authentication, yet no developer wants to deal with authentication. Simple Auth embeds authentication into the API so you

James Clancey 166 Dec 22, 2022
Help you to build pull-down refresh and pull-up loading in the simplest way.

frefresh Help you to build pull-down refresh and pull-up loading in the simplest way. Although unprecedented simplicity, but the effect is amazing. It

Fliggy Mobile 427 Nov 26, 2022
This library provides the optimized and easiest way to authenticate with Mastodon's OAuth 2.0 in your Flutter app 🎯

The Optimized and Easiest Way to Integrate OAuth 2.0 with Mastodon API in Flutter ?? 1. Guide ?? 1.1. Getting Started ⚡ 1.1.1. Install Library 1.1.2.

Mastodon.dart 11 Jul 7, 2023
By using Flutter Local Auth users can authenticate with Fingerprint & Touch ID in Flutter.

Flutter Tutorial - Fingerprint & Touch ID - Local Auth By using Flutter Local Auth users can authenticate with Fingerprint & Touch ID in Flutter. Soci

Johannes Milke 37 Dec 15, 2022