GithubHelp home page GithubHelp logo

clancey / simple_auth Goto Github PK

View Code? Open in Web Editor NEW
352.0 14.0 107.0 583 KB

The Simplest way to Authenticate in Flutter

License: MIT License

Dart 64.40% Java 17.12% Objective-C 13.29% Ruby 3.45% Shell 0.83% Swift 0.91%
flutter flutter-plugin dart dart-library authentication

simple_auth's Introduction

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
  • 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, 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

simple_auth's People

Contributors

alexkblount avatar brettpappas avatar brooooooklyn avatar c-alexander avatar clancey avatar coreycole avatar danielbluelab avatar david-mccoy avatar einjunge99 avatar fbcouch avatar fredericp avatar gitter-badger avatar glachac avatar gobinath1080 avatar hackengineer avatar iqbalhood avatar jeffosmith avatar maskys avatar matthewrice345 avatar miyoyo avatar ncains avatar scottmacdougall avatar sjmcdowall avatar trevorwang avatar uwemeier-sclable avatar vitaly-v avatar vyrotek avatar wsdt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

simple_auth's Issues

question about configuring GoogleApi

i learned to change the following 2 places for my client data:
https://github.com/Clancey/simple_auth/blob/master/simple_auth_flutter_example/lib/main.dart#L75
https://github.com/Clancey/simple_auth/blob/master/simple_auth_flutter_example/android/app/src/main/AndroidManifest.xml#L43

should my application type be android or web application when trying to use this with flutter? when using android for the type, i get a message: "custom scheme URIs are not allowed for 'WEB' client type."
if i should use web application for the type, could you explain a bit why that is instead of android for the type?
thanks for your help!

Dropbox API: cancelled exception

I am trying to authenticate user on Dropbox. The deep link and login to Dropbox account works fine, the user gets redirected to Dropbox website and after login allows all necessary prompts but gives cancelled exception after that. Here is the sample project.

I have included this in 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.googleusercontent.apps.682823335381-iba20i3fst8298mrn5c1ov052sg40v2g" />
        </intent-filter>
    </activity>

Logo Design Offer For Simple Auth

Hello Sir. I'm a UI/UX and Graphics Designer. who has contacted you via email last week.
This is my logo proposal for your application.
I'm very welcome if you have any comments, opinions, or revisions. Please just tell me.
I'll provide all file types and sizes you needed.
Hope you like it

simpleauth

Thanks before.
Regards,
@iqbalhood

microsoftLive.dart needs updating

microsoftLive.dart needs to be updated to use the Azure AD v2.0. The v2.0 endpoints supports both the Aure AD tenants and consumer accounts like hotmail/outlook. Please see

https://developer.microsoft.com/en-us/graph/docs/concepts/auth_overview

The token endpoints for v2 are:

https://login.microsoftonline.com/common/oauth2/v2.0/authorize
https://login.microsoftonline.com/common/oauth2/v2.0/token

The other change is for Redirect URI's: For native and mobile apps this is a URI assigned by Azure AD. -- according to the first link that I provided. By Azure AD they are referring to 'common'

The third change is that the client_secret is NOT required for 'native' apps.

If you get a chance to make the update, I'll be happy to test it and write usage documentation for the MicrosoftLive component

Thanks

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!

AAD demo doesn't work

I use the following configuration, but it showed me an dialog

  final simpleAuth.AzureADApi azureApi = new simpleAuth.AzureADApi(
      "azure",
      azureClientId,
      "https://login.microsoftonline.com/$azureTennant/oauth2/token",
      "https://graph.microsoft.com/",
      "https://login.microsoftonline.com/$azureTennant/oauth2/authorize",
      "urn:ietf:wg:oauth:2.0:oob");

screen shot 2018-12-21 at 9 31 01 am

Azure B2C compatibility

Does this work with Azure B2C? I built a whole system around their stuff and then had to move from Xamarin to Flutter and while I can use Firecloud Auth, I was hoping to stick with MS for authentication.

Looks pretty great, otherwise.

TIA

Integrating with keycloak.

Hello, we're using keycloak for authentication/autherization that uses openid connect protocol.
I'm trying to implement authorization for flutter app with simple auth, but don't have any understanding how to do that. I haven't found any discovery function for that.

Small guide about integrating with custom providers would be really appreciable.
Thanks in advance.

More a question than an issue

Please excuse my ignorance. Exactly where in a DART file do we put the 'generator'
@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> getCurrentUserInfo();
}

I have the following 2 imports:
import 'package:simple_auth/simple_auth.dart';
import 'package:simple_auth_generator/simple_auth_generator.dart';

BUT
void getUserCredentials() async {
var api = new GoogleTestApi("google");
var user = await api.getCurrentUserInfo();
}
does not recognize GoogleTestAPI

Unable to fetch cached account from Dropbox provider

I have been trying to get this working with Dropbox but I keep running into problems. The one I am stuck on now is that after I have authenticated and allowed access to my app - I keep getting prompted to allow access whenever I make an API call.

I believe the problem is with loadAccountFromCache(). The method is able to retrieve the credentials from authStorage but it fails when it gets to getAccountFromMap<T>(data).

Here is the error I see:

I/flutter (13160): NoSuchMethodError: The getter 'iterator' was called on null.
I/flutter (13160): Receiver: null
I/flutter (13160): Tried calling: iterator

I will continue to hunt for why this is happening but I am struggling to understand why it gets tripped up here. I tested it using Google as the provider just to make sure my workflow wasn't missing a step.

Another success/callback (support) question

I got it almost working - the custom callback is called and the authCode is set, completer is completed, but then I also get an error when it from somewhere tries to parse some html, and the completer is then also trying to cancel, but future is already complete..

screen shot 2018-10-08 at 16 44 34

`2018-10-08 16:44:30.924 6759-6834/com.example.simpleauthflutterexample E/flutter: [ERROR:flutter/shell/common/shell.cc(181)] Dart Error: Unhandled exception:
FormatException: Unexpected character (at line 3, character 1)

^

#0      _MyHomePageState.login (file:///Users/bjorck/Projects/safe/simple_auth/simple_auth_flutter_example/lib/main.dart:401:7)
<asynchronous suspension>
#1      _MyHomePageState.build.<anonymous closure> (file:///Users/bjorck/Projects/safe/simple_auth/simple_auth_flutter_example/lib/main.dart:135:15)
#2      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:503:14)
#3      _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:558:30)

`
Any hint on how to debug what that is?

This site can't be reached: google api

from comment on #15 after it was closed:
final simpleAuth.GoogleApi googleApi = new simpleAuth.GoogleApi("google",
"992461286651-k3tsbcreniknqptanrugsetiimt0lkvo.apps.googleusercontent.com",
"http://localhost",
clientSecret: "avrYAIxweNZwcHpsBlIzTp04",
scopes: [
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/userinfo.profile"
]);

is this how i should update it with the latest change? i don't know what to use for the redirecturl.

and, i don't to the choose an acct screen with the latest..:
image

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: #15 (comment)

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

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

Incompatible with http 0.12.0

Because simple_auth_flutter >=1.0.6 depends on simple_auth ^1.0.6 which depends on http ^0.11.0, simple_auth_flutter >=1.0.6 requires http ^0.11.0.
So, because flutter_app depends on both http ^0.12.0 and simple_auth_flutter ^1.0.7, version solving failed.

Feature Request - Implement PKCE

Feature Request - Implement PKCE.

PKCE is standard for public clients, a mobile app is considered a public client; therefore a client secret is no longer secure. PKCE fixes this, the simple_auth library is great, but it would be much appreciated if you could implement PKCE.

Tip: Identity Server 4 has PKCE support out of the box, so it's easy to test against.

Finding out if a user is signed in *without* authenticating them if they're not.

Hi,

I am currently working on an app where I'd like to give the user the option to sign in, by clicking a button, and sign them in automatically if they've done so in the past.

I couldn't find any function that seems to check if a user is signed in validly without giving them the browser page if they're not.

Loading the account from cache and checking if it's .valid should work, but I don't think I'm supposed to call that manually.

Is there a convenience method for this, and/or an option to send requests/use functions while specifying to fail, instead of trying to log in if it's not?

If not, is this a reasonable use case to add? I don't mind adding and documenting it myself at all, but I am worried if it's out of scope?

Thanks for making this awesome library anyway, saved me a ton of time!

Azure AD example broken

Nothing happens when clicking login for azure, except logging of the following

E/MethodChannel#simple_auth_flutter/showAuthenticator( 6889): Failed to handle method call
E/MethodChannel#simple_auth_flutter/showAuthenticator( 6889): java.lang.IllegalArgumentException: Unsupported value: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference
E/MethodChannel#simple_auth_flutter/showAuthenticator( 6889): 	at io.flutter.plugin.common.StandardMessageCodec.writeValue(StandardMessageCodec.java:293)
E/MethodChannel#simple_auth_flutter/showAuthenticator( 6889): 	at io.flutter.plugin.common.StandardMethodCodec.encodeErrorEnvelope(StandardMethodCodec.java:70)
E/MethodChannel#simple_auth_flutter/showAuthenticator( 6889): 	at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler$1.error(MethodChannel.java:199)
E/MethodChannel#simple_auth_flutter/showAuthenticator( 6889): 	at clancey.simpleauth.simpleauthflutter.SimpleAuthFlutterPlugin.onMethodCall(SimpleAuthFlutterPlugin.java:63)
E/MethodChannel#simple_auth_flutter/showAuthenticator( 6889): 	at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:191)
E/MethodChannel#simple_auth_flutter/showAuthenticator( 6889): 	at io.flutter.view.FlutterNativeView.handlePlatformMessage(FlutterNativeView.java:163)
E/MethodChannel#simple_auth_flutter/showAuthenticator( 6889): 	at android.os.MessageQueue.nativePollOnce(Native Method)
E/MethodChannel#simple_auth_flutter/showAuthenticator( 6889): 	at android.os.MessageQueue.next(MessageQueue.java:325)
E/MethodChannel#simple_auth_flutter/showAuthenticator( 6889): 	at android.os.Looper.loop(Looper.java:142)
E/MethodChannel#simple_auth_flutter/showAuthenticator( 6889): 	at android.app.ActivityThread.main(ActivityThread.java:6541)
E/MethodChannel#simple_auth_flutter/showAuthenticator( 6889): 	at java.lang.reflect.Method.invoke(Native Method)
E/MethodChannel#simple_auth_flutter/showAuthenticator( 6889): 	at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
E/MethodChannel#simple_auth_flutter/showAuthenticator( 6889): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)


2018-10-03 17:26:45.119 7605-7605/com.example.simpleauthflutterexample E/MethodChannel#simple_auth_flutter/showAuthenticator: Failed to handle method call
    java.lang.IllegalArgumentException: Unsupported value: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference
        at io.flutter.plugin.common.StandardMessageCodec.writeValue(StandardMessageCodec.java:293)
        at io.flutter.plugin.common.StandardMethodCodec.encodeErrorEnvelope(StandardMethodCodec.java:70)
        at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler$1.error(MethodChannel.java:199)
        at clancey.simpleauth.simpleauthflutter.SimpleAuthFlutterPlugin.onMethodCall(SimpleAuthFlutterPlugin.java:63)
        at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:191)
        at io.flutter.view.FlutterNativeView.handlePlatformMessage(FlutterNativeView.java:163)
        at android.os.MessageQueue.nativePollOnce(Native Method)
        at android.os.MessageQueue.next(MessageQueue.java:325)
        at android.os.Looper.loop(Looper.java:142)
        at android.app.ActivityThread.main(ActivityThread.java:6541)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
2018-10-03 17:26:45.133 1390-1390/? D/gralloc_ranchu: gralloc_alloc: Creating ashmem region of size 7753728
2018-10-03 17:26:45.139 7605-7644/com.example.simpleauthflutterexample E/flutter: [ERROR:flutter/shell/common/shell.cc(181)] Dart Error: Unhandled exception:
    PlatformException(error, Unsupported value: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference, null)
    #0      StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:551:7)
    #1      MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:279:18)
    <asynchronous suspension>
    #2      SimpleAuthFlutter.showAuthenticator (package:simple_auth_flutter/simple_auth_flutter.dart:27:33)
    <asynchronous suspension>
    #3      OAuthApi.performAuthenticate (package:simple_auth/src/oauth/oauthApi.dart:86:30)
    <asynchronous suspension>
    #4      AuthenticatedApi.authenticate (package:simple_auth/src/api/authenticatedApi.dart:20:54)
    <asynchronous suspension>
    #5      _MyHomePageState.login (file:///Users/bjorck/Projects/safe/simple_auth/simple_auth_flutter_example/lib/main.dart:394:31)
    <asynchronous suspension>
    #6      _MyHomePageState.build.<anonymous closure> (file:///Users/bjorck/Projects/safe/simple_auth/simple_auth_flutter_example/lib/main.dart:133:15)
    #7      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:503:14)
    #8      _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:558:30)
    #9      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:102:24)
    #10     TapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:242:9)
    #11     TapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:204:7)
    #12     GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:156:27)
    #13     _WidgetsFlutterBinding&BindingBase&GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:147:20)
    #14     _WidgetsFlutterBinding&BindingBase&GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:121:22)
    #15     _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:101:7)
    #16     _WidgetsFlutterBinding&BindingBase&GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:64:7)
    #17     _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:48:7)
    #18     _invoke1 (dart:ui/hooks.dart:142:13)
    #19     _dispatchPointerDataPacket (dart:ui/hooks.dart:99:5)

Callback

Hi,
I've a callback issue, I'm unable to catch the callback when I try to log on Teamsnap.
Teamsnapp need a https url as callback and I'm not able to catch it with simpleauthflutter.

Here is my 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="https://com.test.testsimpleauthflutter/redirct" />
            </intent-filter>
        </activity>

I understood that https is unusable, but have you an idea on the way to follow to use it?

Question - Authentication Success Message

Hi there,

I am a pretty new to programming and started learning Flutter recently. Apologies if my question is way too basic or does not belong under this thread.

I am running simple_auth_flutter and am testing authentication to Instagram. I am able to get the authentication screen and Instagram directs me to the callback URI. Once there I was expecting to get the showMessage success:

var success = await api.authenticate();
showMessage("Logged in success: $success");

I am getting stuck at the callback screen with only a cancel button, which cancels the authentication. I do not see the success message.

I basically would like to know how I can go back to main.dart once the user is authenticated and grab the authorization uri to get Instagram's token and be able to access the user's information.

Your help would be much appreciated.

Thanks in advance!

Error using googleApi

final simpleAuth.GoogleApi googleApi = new simpleAuth.GoogleApi("google",
      "992461286651-k3tsbcreniknqptanrugsetiimt0lkvo.apps.googleusercontent.com",
      clientSecret: "avrYAIxweNZwcHpsBlIzTp04",
      scopes: [
        "https://www.googleapis.com/auth/userinfo.email",
        "https://www.googleapis.com/auth/userinfo.profile"
      ]);

final googleLoginButton = Padding(
      padding: EdgeInsets.symmetric(vertical: 16.0),
      child: Material(
        borderRadius: BorderRadius.circular(30.0),
        shadowColor: Colors.lightBlueAccent.shade100,
        elevation: 5.0,
        child: MaterialButton(
          minWidth: 200.0,
          height: 42.0,
          onPressed: () async {
              try {
                var user = await googleApi.getUserProfile();
                showMessage("${user.name} logged in");
              } catch (e) {
                showError(e);
              }
            },
          color: Colors.lightBlueAccent,
          child: Text('Log In Using Google', style: TextStyle(color: Colors.white)),
        ),
      ),
    );

i also have set in testapp\android\app\src\main\AndroidManifest.xml , the same key:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testapp">

    <!-- The INTERNET permission is required for development. Specifically,
         flutter needs it to communicate with the running application
         to allow setting breakpoints, to provide hot reload, etc.
    -->
    <uses-permission android:name="android.permission.INTERNET"/>

    <!-- io.flutter.app.FlutterApplication is an android.app.Application that
         calls FlutterMain.startInitialization(this); in its onCreate method.
         In most cases you can leave this as-is, but you if you want to provide
         additional functionality it is fine to subclass or reimplement
         FlutterApplication and put your custom class here. -->
    <application
        android:name="io.flutter.app.FlutterApplication"
        android:label="app1"
        android:icon="@mipmap/ic_launcher">
        <activity
            android:name=".MainActivity"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
            <!-- This keeps the window background of the activity showing
                 until Flutter renders its first frame. It can be removed if
                 there is no splash screen (such as the default splash screen
                 defined in @style/LaunchTheme). -->
            <meta-data
                android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
                android:value="true" />
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </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>
    </application>
</manifest>

here's the error i get when i try the button:

type 'int' is not a subtype of type 'String'

also, if i try to simply change 992461286651-k3tsbcreniknqptanrugsetiimt0lkvo to my google android project's key, then i get this error instead:

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

what's going on with error when trying to use the test project and what might i be doing wrong in my google android project, such that when using its key, i get a different error?

thanks,
my google project looks like this:
image

image

How to create JsonSerializable to send a POST with body

I have tried a number of ways to create an API definition that sends a POST request with the parameters as part of the body.

Dropbox requires calls to it's API to send it's parameters as JSON body in a post request. I tried creating a definition but I don't know how to pass the body:

@DropboxApiDeclaration("DropboxTestApi", "<client_id>", "<client_secret>", "<redirect>")
abstract class DropboxTestDefinition {
    @Post(url: "https://api.dropboxapi.com/2/files/list_folder")
    Future<Response<Object>> getFileList();
}

Any chance you can provide an example?

Azure AD doesn't work on Android

Here's the code. It works well on iOS, but not on Android.

final AzureADApi azureApi = AzureADApi(
    "azure",
    azureClientId,
    "https://login.microsoftonline.com/$azureTennant/oauth2/token",
    "https://graph.microsoft.com/",
    "https://login.microsoftonline.com/$azureTennant/oauth2/authorize",
    "urn:ietf:wg:oauth:2.0:oob");

screen shot 2018-12-23 at 9 26 43 pm

HttpMethod.Post - No converter found for type _InternalLinkedHashMap<String, String>

Error on POST Requests (line Response response = await send(request);) . HttpMethod.GET requests seem good.

  void addConnect() async{
    var url = '${Util.serverBaseUrl}';
    var body = {
      'scope': 'email',
    };
    Request request = Request(HttpMethod.Post, url, body: body, authenticated: true);
    Response response = await send(request);
  }

API


class MyApi extends OAuthApi {
  MyApi(String identifier, String clientId, String clientSecret,
      String redirectUrl,
      {List<String> scopes,
      http.Client client,
      Converter converter,
      AuthStorage authStorage})
      : super(
            identifier,
            clientId,
            clientSecret,
            "http://foobar12.ngrok.io/oauth/token",
            "http://foobar12.ngrok.io/oauth/authorize",
            redirectUrl,
            client: client,
            scopes: scopes,
            converter: converter,
            authStorage: authStorage) {
    this.scopes = scopes;
  }

  @override
  Authenticator getAuthenticator() => MyApiAuthenticator(identifier, clientId,
      clientSecret, tokenUrl, authorizationUrl, redirectUrl, scopes);

  Future<MyApiUser> getUserProfile() async {
    var request =
    //    new Request(HttpMethod.Get, "http://10.0.2.2:8080/api/profile");
    new Request(HttpMethod.Get, "http://foobar12.ngrok.io/api/home");
    var resp = await send(request);
    var json = convert.jsonDecode(resp.body);
    return MyApiUser.fromjson(json);
  }

  @override
  Future<OAuthAccount> getAccountFromAuthCode(
      WebAuthenticator authenticator) async {
    if (tokenUrl?.isEmpty ?? true) throw new Exception("Invalid tokenURL");
    var postData = await authenticator.getTokenPostData(clientSecret);

    final HttpClient client = new HttpClient();
    client.findProxy = null;
    var account =  null;
    final accessTokenUri = createAccessTokenUrl(tokenUrl, postData);
    print(accessTokenUri);
    client.addCredentials(Uri.parse(accessTokenUri), 'foobar',
        new HttpClientBasicCredentials(clientId, clientSecret));
    await client
        .postUrl(Uri.parse(accessTokenUri))
        .then((HttpClientRequest request) {
      request.headers.contentType =
          new ContentType("application", "json", charset: "utf-8");
      return request.close();
    }).then((HttpClientResponse response) async {
      String content = await response.transform(utf8.decoder).join();
      print(content);
      var map = convert.json.decode(content);
      var result = OAuthResponse.fromJson(map);
       account = OAuthAccount(identifier,
          created: DateTime.now().toUtc(),
          expiresIn: result.expiresIn,
          idToken: result.idToken,
          refreshToken: result.refreshToken,
          scope: authenticator.scope,
          tokenType: result.tokenType,
          token: result.accessToken);
    });
    return account;
  }
}

  void addConnect() async{
    var url = '${Util.serverBaseUrl}';
    var body = {
      'scope': 'email',
    };
    Request request = Request(HttpMethod.Post, url, body: body, authenticated: true);
    Response response = await send(request);
  }



String createAccessTokenUrl(tokenUrl, postData) {
  String code = postData['code'];
  String grantType = postData['grant_type'];
  String redirectUri = postData['redirect_uri'];
  return tokenUrl +
      "?code=" +
      code +
      "&grant_type=" +
      grantType +
      "&redirect_uri=" +
      redirectUri;
}

class MyApiAuthenticator extends OAuthAuthenticator {
  MyApiAuthenticator(String identifier, String clientId, String clientSecret,
      String tokenUrl, String baseUrl, String redirectUrl, List<String> scopes)
      : super(identifier, clientId, clientSecret, tokenUrl, baseUrl,
            redirectUrl) {
    this.scope = scopes;
    useEmbeddedBrowser = true;
  }


}

class MyApiUser implements JsonSerializable {
  String name;
  String email;
  MyApiUser({this.name, this.email});

  factory MyApiUser.fromjson(Map<String, dynamic> json) =>
      new MyApiUser(name: json["name"], email: json["email"]);

  @override
  Map<String, dynamic> toJson() => {"name": name, "email": email};
}

LinkedIn OAuth - NoSuchMethodError

Only on LinkedIn authentication I got this error:

NoSuchMethodError: The method 'resetAuthenticator' was called on null. Receiver: null. Tried calling: resetAuthenticator()

I'am using the code in example.

Flutter doctor -v

[✓] Flutter (Channel beta, v0.7.3, on Mac OS X 10.13.6 17G65, locale pt-BR)
    • Flutter version 0.7.3 at /Users/raphael/development/flutter
    • Framework revision 3b309bda07 (13 days ago), 2018-08-28 12:39:24 -0700
    • Engine revision af42b6dc95
    • Dart version 2.1.0-dev.1.0.flutter-ccb16f7282

[✓] Android toolchain - develop for Android devices (Android SDK 27.0.3)
    • Android SDK at /Users/raphael/Library/Android/sdk
    • Android NDK at /Users/raphael/Library/Android/sdk/ndk-bundle
    • Platform android-27, build-tools 27.0.3
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-915-b08)
    • All Android licenses accepted.

[✓] iOS toolchain - develop for iOS devices (Xcode 9.4.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 9.4.1, Build version 9F2000
    • ios-deploy 1.9.2
    • CocoaPods version 1.5.2

[✓] Android Studio (version 3.0)
    • Android Studio at /Applications/Android Studio.app/Contents
    ✗ Flutter plugin not installed; this adds Flutter specific functionality.
    ✗ Dart plugin not installed; this adds Dart specific functionality.
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-915-b08)

[✓] VS Code (version 1.27.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 2.18.0

[✓] Connected devices (1 available)
    • iPhone 5s • EA3B5064-080D-4DDC-AC99-0F09B19962BA • ios • iOS 11.4 (simulator)

• No issues found!

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)

Request AppDelegate.swift

Hi!
I just wanted to know if it was possible to have the swift code for the AppDelegate.swift and not only the AppDelegate.h since if you start the project with swift enabled in android studio it will provide only the swift one.
Thanks!

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

Redirect scheme AzureAd failing

I have configured a callback scheme as follows:

<data android:scheme="com.foo.app" />
 <data android:host="auth" />

which should translate to com.foo.app://auth

I get to login the login screen ok. But after submitting the login form I get a popup which says:
Exception: Unable to get an AuthToken from the server.

I did some debugging and found that I get the following error in

AzureADAuthenticator._redirectUri.origin

Unhandled exception: Bad state. Origin is only applicable to schemes http and https: com.foo.app://auth
SimpleUri.origin(dart:core/uri.dart4257:7)

Steam support

Hey there,

I am currently looking for a library that I can use to obtain the user's ID via OpenID. The only thing that steam provides is the endpoint url. There is no client secret involved as far as I can tell and the API can merely be used to return the user ID.
How would I use the package ? Is there some generic OpenID class?

Using that ID I'd like to make calls to the official web API using an API key. Would it be possible to write own annotations that can be used to generate an API class ? As far as I can tell it's just a normal json API, no authentication (except for the API key)

Authenticator.class: Only WebAuthenticator works

When logging in with correct credentials we get redirected as expected to our redirect uri.
Unfortunately, only the InstagramApi closes the window and we receive the token etc.

Facebook, Github, and all other do not close the window as those Authenticator-childs do not respond.

So, when closing the browser window we get the Cancelled Exception message.
As we saw this issue in another issue: Our user, api credentials and the redirect uris are correct so that might not be the cause.

Thank you in advance :)

App sits on redirect page in browser

Hey,

Do you have an example for OAuthApi ??

I am trying to connect to Meetup (Android currently). It shows the login page, etc. I successfully login and it then shows the redirect page and just sits there, in the browser. Never exits back to the app.

Is there something i am missing ?

Blank Screen for IOS when embeddedBrowser=true

App's internal browser (embeddedBrowser=true) fails to display site's authentication form (displays blank white screen) unlike the External Browser (embeddedBrowser=false), which has correct behaviour. No issues with Android.

class MyApi extends OAuthApi {
  MyApi(String identifier, String clientId, String clientSecret,
      String redirectUrl,
      {List<String> scopes,
      http.Client client,
      Converter converter,
      AuthStorage authStorage})
      : super(
            identifier,
            clientId,
            clientSecret,
            "http://foobar12.ngrok.io/oauth/token",
            "http://foobar12.ngrok.io/oauth/authorize",
            redirectUrl,
            client: client,
            scopes: scopes,
            converter: converter,
            authStorage: authStorage) {
    this.scopes = scopes;
  }

  @override
  Authenticator getAuthenticator() => MyApiAuthenticator(identifier, clientId,
      clientSecret, tokenUrl, authorizationUrl, redirectUrl, scopes);

  Future<MyApiUser> getUserProfile() async {
    var request =
    //    new Request(HttpMethod.Get, "http://10.0.2.2:8080/api/profile");
    new Request(HttpMethod.Get, "http://foobar12.ngrok.io/api/home");
    var resp = await send(request);
    var json = convert.jsonDecode(resp.body);
    return MyApiUser.fromjson(json);
  }

  @override
  Future<OAuthAccount> getAccountFromAuthCode(
      WebAuthenticator authenticator) async {
    if (tokenUrl?.isEmpty ?? true) throw new Exception("Invalid tokenURL");
    var postData = await authenticator.getTokenPostData(clientSecret);

    final HttpClient client = new HttpClient();
    client.findProxy = null;
    var account =  null;
    final accessTokenUri = createAccessTokenUrl(tokenUrl, postData);
    print(accessTokenUri);
    client.addCredentials(Uri.parse(accessTokenUri), 'foobar',
        new HttpClientBasicCredentials(clientId, clientSecret));
    await client
        .postUrl(Uri.parse(accessTokenUri))
        .then((HttpClientRequest request) {
      request.headers.contentType =
          new ContentType("application", "json", charset: "utf-8");
      return request.close();
    }).then((HttpClientResponse response) async {
      String content = await response.transform(utf8.decoder).join();
      print(content);
      var map = convert.json.decode(content);
      var result = OAuthResponse.fromJson(map);
       account = OAuthAccount(identifier,
          created: DateTime.now().toUtc(),
          expiresIn: result.expiresIn,
          idToken: result.idToken,
          refreshToken: result.refreshToken,
          scope: authenticator.scope,
          tokenType: result.tokenType,
          token: result.accessToken);
    });
    return account;
  }
}

String createAccessTokenUrl(tokenUrl, postData) {
  String code = postData['code'];
  String grantType = postData['grant_type'];
  String redirectUri = postData['redirect_uri'];
  return tokenUrl +
      "?code=" +
      code +
      "&grant_type=" +
      grantType +
      "&redirect_uri=" +
      redirectUri;
}

class MyApiAuthenticator extends OAuthAuthenticator {
  MyApiAuthenticator(String identifier, String clientId, String clientSecret,
      String tokenUrl, String baseUrl, String redirectUrl, List<String> scopes)
      : super(identifier, clientId, clientSecret, tokenUrl, baseUrl,
            redirectUrl) {
    this.scope = scopes;
    useEmbeddedBrowser = true;
  }


}

class MyApiUser implements JsonSerializable {
  String name;
  String email;
  MyApiUser({this.name, this.email});

  factory MyApiUser.fromjson(Map<String, dynamic> json) =>
      new MyApiUser(name: json["name"], email: json["email"]);

  @override
  Map<String, dynamic> toJson() => {"name": name, "email": email};
}

AndroidX Compatability

simple_auth_flutter needs to be upgraded to support the AndroidX libraries.

Launching lib/main.dart on Android SDK built for x86 in debug mode...
registerResGeneratingTask is deprecated, use registerGeneratedResFolders(FileCollection)
registerResGeneratingTask is deprecated, use registerGeneratedResFolders(FileCollection)
registerResGeneratingTask is deprecated, use registerGeneratedResFolders(FileCollection)
registerResGeneratingTask is deprecated, use registerGeneratedResFolders(FileCollection)
registerResGeneratingTask is deprecated, use registerGeneratedResFolders(FileCollection)
/Users/davidmccoy/.pub-cache/hosted/pub.dartlang.org/simple_auth_flutter-2.0.1/android/src/main/java/clancey/simpleauth/simpleauthflutter/CustomTabActivityHelper.java:21: error: cannot find symbol
import android.support.customtabs.CustomTabsClient;
                                 ^
  symbol:   class CustomTabsClient
  location: package android.support.customtabs
/Users/davidmccoy/.pub-cache/hosted/pub.dartlang.org/simple_auth_flutter-2.0.1/android/src/main/java/clancey/simpleauth/simpleauthflutter/CustomTabActivityHelper.java:22: error: cannot find symbol
import android.support.customtabs.CustomTabsIntent;
                                 ^
  symbol:   class CustomTabsIntent
  location: package android.support.customtabs
/Users/davidmccoy/.pub-cache/hosted/pub.dartlang.org/simple_auth_flutter-2.0.1/android/src/main/java/clancey/simpleauth/simpleauthflutter/CustomTabActivityHelper.java:23: error: cannot find symbol
import android.support.customtabs.CustomTabsServiceConnection;
                                 ^
  symbol:   class CustomTabsServiceConnection
  location: package android.support.customtabs
/Users/davidmccoy/.pub-cache/hosted/pub.dartlang.org/simple_auth_flutter-2.0.1/android/src/main/java/clancey/simpleauth/simpleauthflutter/CustomTabActivityHelper.java:24: error: cannot find symbol
import android.support.customtabs.CustomTabsSession;
                                 ^
  symbol:   class CustomTabsSession
  location: package android.support.customtabs
/Users/davidmccoy/.pub-cache/hosted/pub.dartlang.org/simple_auth_flutter-2.0.1/android/src/main/java/clancey/simpleauth/simpleauthflutter/ServiceConnectionCallback.java:16: error: cannot find symbol
import android.support.customtabs.CustomTabsClient;
                                 ^
  symbol:   class CustomTabsClient
  location: package android.support.customtabs
/Users/davidmccoy/.pub-cache/hosted/pub.dartlang.org/simple_auth_flutter-2.0.1/android/src/main/java/clancey/simpleauth/simpleauthflutter/CustomTabActivityHelper.java:36: error: cannot find symbol
    private CustomTabsSession mCustomTabsSession;
            ^
  symbol:   class CustomTabsSession
  location: class CustomTabActivityHelper
/Users/davidmccoy/.pub-cache/hosted/pub.dartlang.org/simple_auth_flutter-2.0.1/android/src/main/java/clancey/simpleauth/simpleauthflutter/CustomTabActivityHelper.java:37: error: cannot find symbol
    private CustomTabsClient mClient;
            ^
  symbol:   class CustomTabsClient
  location: class CustomTabActivityHelper
/Users/davidmccoy/.pub-cache/hosted/pub.dartlang.org/simple_auth_flutter-2.0.1/android/src/main/java/clancey/simpleauth/simpleauthflutter/CustomTabActivityHelper.java:38: error: cannot find symbol
    private CustomTabsServiceConnection mConnection;
            ^
  symbol:   class CustomTabsServiceConnection
  location: class CustomTabActivityHelper
/Users/davidmccoy/.pub-cache/hosted/pub.dartlang.org/simple_auth_flutter-2.0.1/android/src/main/java/clancey/simpleauth/simpleauthflutter/CustomTabActivityHelper.java:50: error: cannot find symbol
                                     CustomTabsIntent customTabsIntent,
                                     ^
  symbol:   class CustomTabsIntent
  location: class CustomTabActivityHelper
/Users/davidmccoy/.pub-cache/hosted/pub.dartlang.org/simple_auth_flutter-2.0.1/android/src/main/java/clancey/simpleauth/simpleauthflutter/CustomTabActivityHelper.java:84: error: cannot find symbol
    public CustomTabsSession getSession() {
           ^
  symbol:   class CustomTabsSession
  location: class CustomTabActivityHelper
/Users/davidmccoy/.pub-cache/hosted/pub.dartlang.org/simple_auth_flutter-2.0.1/android/src/main/java/clancey/simpleauth/simpleauthflutter/CustomTabActivityHelper.java:129: error: cannot find symbol
    public void onServiceConnected(CustomTabsClient client) {
                                   ^
  symbol:   class CustomTabsClient
  location: class CustomTabActivityHelper
/Users/davidmccoy/.pub-cache/hosted/pub.dartlang.org/simple_auth_flutter-2.0.1/android/src/main/java/clancey/simpleauth/simpleauthflutter/ServiceConnectionCallback.java:26: error: cannot find symbol
    void onServiceConnected(CustomTabsClient client);
                            ^
  symbol:   class CustomTabsClient
  location: interface ServiceConnectionCallback
/Users/davidmccoy/.pub-cache/hosted/pub.dartlang.org/simple_auth_flutter-2.0.1/android/src/main/java/clancey/simpleauth/simpleauthflutter/SimpleAuthCallbackActivity.java:5: error: package android.support.annotation does not exist
import android.support.annotation.Nullable;
                                 ^
/Users/davidmccoy/.pub-cache/hosted/pub.dartlang.org/simple_auth_flutter-2.0.1/android/src/main/java/clancey/simpleauth/simpleauthflutter/CustomTabsAuthenticator.java:8: error: cannot find symbol
import android.support.customtabs.CustomTabsIntent;
                                 ^
  symbol:   class CustomTabsIntent
  location: package android.support.customtabs
/Users/davidmccoy/.pub-cache/hosted/pub.dartlang.org/simple_auth_flutter-2.0.1/android/src/main/java/clancey/simpleauth/simpleauthflutter/ServiceConnection.java:18: error: cannot find symbol
import android.support.customtabs.CustomTabsClient;
                                 ^
  symbol:   class CustomTabsClient
  location: package android.support.customtabs
/Users/davidmccoy/.pub-cache/hosted/pub.dartlang.org/simple_auth_flutter-2.0.1/android/src/main/java/clancey/simpleauth/simpleauthflutter/ServiceConnection.java:19: error: cannot find symbol
import android.support.customtabs.CustomTabsServiceConnection;
                                 ^
  symbol:   class CustomTabsServiceConnection
  location: package android.support.customtabs
/Users/davidmccoy/.pub-cache/hosted/pub.dartlang.org/simple_auth_flutter-2.0.1/android/src/main/java/clancey/simpleauth/simpleauthflutter/ServiceConnection.java:27: error: cannot find symbol
public class ServiceConnection extends CustomTabsServiceConnection {
                                       ^
  symbol: class CustomTabsServiceConnection
/Users/davidmccoy/.pub-cache/hosted/pub.dartlang.org/simple_auth_flutter-2.0.1/android/src/main/java/clancey/simpleauth/simpleauthflutter/ServiceConnection.java:36: error: cannot find symbol
    public void onCustomTabsServiceConnected(ComponentName name, CustomTabsClient client) {
                                                                 ^
  symbol:   class CustomTabsClient
  location: class ServiceConnection
/Users/davidmccoy/.pub-cache/hosted/pub.dartlang.org/simple_auth_flutter-2.0.1/android/src/main/java/clancey/simpleauth/simpleauthflutter/SimpleAuthCallbackActivity.java:9: error: cannot find symbol
    protected void onCreate(@Nullable Bundle savedInstanceState) {
                             ^
  symbol:   class Nullable
  location: class SimpleAuthCallbackActivity
/Users/davidmccoy/.pub-cache/hosted/pub.dartlang.org/simple_auth_flutter-2.0.1/android/src/main/java/clancey/simpleauth/simpleauthflutter/CustomTabActivityHelper.java:112: error: cannot find symbol
        CustomTabsClient.bindCustomTabsService(activity, packageName, mConnection);
        ^
  symbol:   variable CustomTabsClient
  location: class CustomTabActivityHelper
/Users/davidmccoy/.pub-cache/hosted/pub.dartlang.org/simple_auth_flutter-2.0.1/android/src/main/java/clancey/simpleauth/simpleauthflutter/CustomTabActivityHelper.java:122: error: cannot find symbol
        CustomTabsSession session = getSession();
        ^
  symbol:   class CustomTabsSession
  location: class CustomTabActivityHelper
/Users/davidmccoy/.pub-cache/hosted/pub.dartlang.org/simple_auth_flutter-2.0.1/android/src/main/java/clancey/simpleauth/simpleauthflutter/CustomTabsAuthenticator.java:39: error: package CustomTabsIntent does not exist
        final CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
                              ^
/Users/davidmccoy/.pub-cache/hosted/pub.dartlang.org/simple_auth_flutter-2.0.1/android/src/main/java/clancey/simpleauth/simpleauthflutter/CustomTabsAuthenticator.java:39: error: package CustomTabsIntent does not exist
        final CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
                                                                     ^
/Users/davidmccoy/.pub-cache/hosted/pub.dartlang.org/simple_auth_flutter-2.0.1/android/src/main/java/clancey/simpleauth/simpleauthflutter/CustomTabsAuthenticator.java:41: error: cannot find symbol
        CustomTabsIntent intent = builder.build();
        ^
  symbol:   class CustomTabsIntent
  location: class CustomTabsAuthenticator
/Users/davidmccoy/.pub-cache/hosted/pub.dartlang.org/simple_auth_flutter-2.0.1/android/src/main/java/clancey/simpleauth/simpleauthflutter/ServiceConnection.java:35: error: method does not override or implement a method from a supertype
    @Override
    ^
/Users/davidmccoy/.pub-cache/hosted/pub.dartlang.org/simple_auth_flutter-2.0.1/android/src/main/java/clancey/simpleauth/simpleauthflutter/ServiceConnection.java:41: error: method does not override or implement a method from a supertype
    @Override
    ^
26 errors

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':simple_auth_flutter:compileDebugJavaWithJavac'.
> Compilation failed; see the compiler error output for details.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 18s
*******************************************************************************************
The Gradle failure may have been because of AndroidX incompatibilities in this Flutter app.
See https://goo.gl/CP92wY for more information on the problem and how to fix it.
*******************************************************************************************
Gradle task assembleDebug failed with exit code 1
Exited (sigterm)

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

Feature Request - Support hybrid flow

If I understand the code correctly, simple_auth is currently hardcoded in WebAuthenticator. In my use-case, I would like to use a hybrid flow to do auth with my own Identity Server and instead pass code Id_token.

Deprecated IOS line in README.md

README.md is no longer valid for swift 4 (see below).

Using line from README.md causes build to fail:

Launching lib/main.dart on iPhone X in debug mode...
Running pod install...
Starting Xcode build...
Xcode build done.
Failed to build iOS app
Error output from Xcode build:

** BUILD FAILED **

Xcode's output:

=== BUILD TARGET Runner OF PROJECT Runner WITH CONFIGURATION Debug ===
The use of Swift 3 @objc inference in Swift 4 mode is deprecated. Please address deprecated @objc inference warnings, test your code with “Use of deprecated Swift 3 @objc inference” logging enabled, and then disable inference by changing the "Swift 3 @objc Inference" build setting to "Default" for the "Runner" target.
=== BUILD TARGET Runner OF PROJECT Runner WITH CONFIGURATION Debug ===
~/flutter_workspace/example/ios/Runner/AppDelegate.swift:20:1: error: expected declaration
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
^
~/flutter_workspace/example/ios/Runner/AppDelegate.swift:6:13: note: in declaration of 'AppDelegate'
@objc class AppDelegate: FlutterAppDelegate {

import UIKit
import Flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}

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

}

Tried changing above to following: 'Use of unresolved identifier 'SimpleAuthFlutterPlugin''.

override func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
return SimpleAuthFlutterPlugin.checkUrl(url)
}

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.

Android Callback scheme not recognised?

Neither of the following working for me.

Redirect url displayed in browser without returning to the app.

Server redirect url: https://example.com/secure

  1.  <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="https"
                 android:host="example.com"
                 android:pathPrefix="/secure"/>
         </intent-filter>
     </activity>
    
  2.  <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="https"
                 android:host="*.example.com"
                 android:pathPrefix="/secure"/>
         </intent-filter>
     </activity>
    

Full AndroidManifest.xml

manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.example">

<!-- The INTERNET permission is required for development. Specifically,
     flutter needs it to communicate with the running application
     to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>

<!-- io.flutter.app.FlutterApplication is an android.app.Application that
     calls FlutterMain.startInitialization(this); in its onCreate method.
     In most cases you can leave this as-is, but you if you want to provide
     additional functionality it is fine to subclass or reimplement
     FlutterApplication and put your custom class here. -->
<application
    android:name="io.flutter.app.FlutterApplication"
    android:label="example"
    android:icon="@mipmap/ic_launcher">
    <activity
        android:name=".MainActivity"
        android:launchMode="singleTop"
        android:theme="@style/LaunchTheme"
        android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
        android:hardwareAccelerated="true"
        android:windowSoftInputMode="adjustResize">
        <!-- This keeps the window background of the activity showing
             until Flutter renders its first frame. It can be removed if
             there is no splash screen (such as the default splash screen
             defined in @style/LaunchTheme). -->
        <meta-data
            android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
            android:value="true" />
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </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="https"
                android:host="*.example.com"
                android:pathPrefix="/secure"/>
        </intent-filter>
    </activity>
</application>

Failed assertion: boolean expression must not be null

useNonce was not initialized

^
[VERBOSE-2:ui_dart_state.cc(148)] Unhandled Exception: Failed assertion: boolean expression must not be null
#0      WebAuthenticator.getInitialUrlQueryParameters 
package:simple_auth/…/api/webAuthenticator.dart:56
<asynchronous suspension>
#1      AzureADAuthenticator.getInitialUrlQueryParameters 
package:simple_auth/…/providers/azureAD.dart:69
<asynchronous suspension>
#2      WebAuthenticator.getInitialUrl 
package:simple_auth/…/api/webAuthenticator.dart:45
<asynchronous suspension>
#3      SimpleAuthFlutter.showAuthenticator 
package:simple_auth_flutter/simple_auth_flutter.dart:29
<asynchronous suspension>
#4      OAuthApi.performAuthenticate 
package:simple_auth/…/oauth/oauthApi.dart:86
<asynchronous suspension>
#5      AuthenticatedApi.authenticate 
package:simple_auth/…/api/authenticatedApi.dart:20
<asynchronous suspension>
#6      Azure.login 
package:flutter_zhihu/azure.dart:32
<asynchronous suspension>
#7      _azureSign.<anonymous closure> (package:flut<…>
flutter: 2019-03-01 13:17:16.951067: LoginPage: FINE: SignStatus.SigningIn

Unneeded returns on void methods giving some problems

Builders don't need to return anything, code_builder doesn't return anything in their own tests either. Not sure why they are, but it blocked me from code generation.

I also got a minor depression from the documentation for the generator libraries :P

Question - How to authenticate against custom AAD protected api's?

Hey there,

we have a few C# API's that are protected by our azure active directory. In our typescript frontends, we use adal.js to authenticate with the clientId and the proper redirectUri. How can I do the same thing with your library? Specifically, I have problems figuring out what to put in each parameter.

final simpleAuth.AzureADApi azureApi = simpleAuth.AzureADApi(
      '<name of the tool>',
      '<clientId>',
      'https://login.microsoftonline.com/<our tenant>/oauth2/token',
      '<what do I put here?>',
      'https://login.microsoftonline.com/<our tenant>/oauth2/authorize',
      redirectUrl: 'msal<generated by app registration portal>://auth');

Can you point me in the right direction?

Thanks!

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.

Exception while loading account from cache

I was testing whether this lib can cache the azure ad authentication. I saw safari page was opened every time the application was restarted.

I looked into this issue, and found that there was an exception when getAccountFromMap was invoked.

  Future<T> loadAccountFromCache<T extends Account>() async {
    var json = await _authStorage.read(key: identifier);
    if (json == null) return null;
    try {
      var data = Convert.jsonDecode(json);
      return getAccountFromMap<T>(data);
    } catch (exception) {
      print(exception);
      return null;
    }
  }

  getAccountFromMap<T extends Account>(Map<String, dynamic> data) =>
      Account.fromJson(data);

"NoSuchMethodError: The getter 'iterator' was called on null.
Receiver: null
Tried calling: iterator"

screen shot 2018-12-25 at 11 04 02 pm

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.