The Simplest way to Authenticate and make Rest API calls in .Net

Overview

Simple Auth

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. Most importantly it works great with traditional Xamarin and Xamarin.Forms

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

Android: Android Build status

iOS/MacOS: Build status

General information

Available on Nuget

Clancey.SimpleAuth

Providers

Current Built in Providers

  • Azure Active Directory
  • Amazon
  • Dropbox
  • Facebook
  • Github
  • Google
  • Instagram
  • Linked In
  • Microsoft Live Connect
  • Twitter

Simple auth ships with some built in providers so you just need to add your keys and scopes.

var scopes = new[]
{
	"https://www.googleapis.com/auth/userinfo.email",
	"https://www.googleapis.com/auth/userinfo.profile"
};
var api = new GoogleApi("google",
	   "clientid",
	   "clientsecret")
{
	Scopes = scopes,
};

var account = await api.Authenticate();

Restful Api Requests

Restful Api Requests couldnt be simpler

var song = await api.Get<Song>("http://myapi/Song/",songId);

Paramaters can be added as part of the path

var todoItem = await api.Get<TodoItem>("http://myapi/user/{UserId}/TodoItem",new Dictionary<string,string>{["UserId"] = "1", ["itemID"] = "22"});

Generates the following Url:

http://myapi/user/1/TodoItem?itemID=22

Attribute your Api Requests (Optional)

[Path("/pet")]
[ContentType("application/json")]
[Accepts("application/json")]
public virtual Task AddPet(Pet body) {
    return Post( body);
}

iOS/Mac Specific

OnePassword Support (iOS)

One password support is for iOS Only.
Simply add the project or the Nuget

Clancey.SimpleAuth.OnePassword

Then call the following line in your iOS project prior to calling api.Authenticate();

SimpleAuth.OnePassword.Activate();

Native Twitter Support via Twitter App

You can use the Twitter app to authenticate with SimpleAuth on iOS.

Add the following to your Info.Plist

// Info.plist
<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>twitterkit-<consumerKey></string>
    </array>
  </dict>
</array>
<key>LSApplicationQueriesSchemes</key>
<array>
    <string>twitter</string>
    <string>twitterauth</string>
</array>

Then call the following line in your iOS AppDelegate FinishedLaunching method;

SimpleAuth.Providers.Twitter.Init();

Also add the following override in your AppDelegate

public override bool OpenUrl (UIApplication app, NSUrl url, NSDictionary options)
{
	if (SimpleAuth.Native.OpenUrl(app, url, options))
		return true;
	return base.OpenUrl(app,url,options);
}

Native Facebook Support via iOS SDK

Simply add the project or the Nuget

Clancey.SimpleAuth.Facebook.iOS

The Facebook SDK requires you modify your info.plist : https://components.xamarin.com/gettingstarted/facebookios

Then call the following line in your iOS AppDelegate FinishedLaunching method;

SimpleAuth.Providers.Facebook.Init(app, options);

Also add the following override in your AppDelegate

public override bool OpenUrl (UIApplication app, NSUrl url, NSDictionary options)
{
	if (SimpleAuth.Native.OpenUrl(app, url, options))
		return true;
	return base.OpenUrl(app,url,options);
}

Native Google Support via iOS SDK

Clancey.SimpleAuth.Google.iOS

The Google SDK can do Cross-Client Login. This allows you to get tokens for the server, with one login.

To use Cross-client you need to set the ServerClientId on the GoogleApi.

Call the following in your FinishedLaunching Method;

SimpleAuth.Providers.Google.Init()

Also add the following to your AppDelegate

public override bool OpenUrl (UIApplication app, NSUrl url, NSDictionary options)
{
	if (SimpleAuth.Native.OpenUrl(app, url, options))
		return true;
	return base.OpenUrl(app,url,options);
}

If you need Cross-client authentication

var api = new GoogleApi("google","client_id"){
	ServerClientId = "server_client_id""
};
var account = await api.Authenticate ();
var serverToken = account.UserData ["ServerToken"];

Troubleshooting

System.Exception: Error Domain=com.google.GIDSignIn Code=-2 "keychain error" UserInfo={NSLocalizedDescription=keychain error}

Under the iOS Build Signing, Custom Entitlements: make sure an entitlement.plist is set

Native SFSafariViewController iOS/MacOS

SFSafariViewController Allows users to use Safari to login, instead of embedded webviews.

Google now requires this mode and is enabled by default for Google Authentication on iOS/MacOS.

To use the Native Safari Authenticator, you are required to add the following snippet in your AppDelegate (iOS Only)

public override bool OpenUrl (UIApplication app, NSUrl url, NSDictionary options)
{
	if (SimpleAuth.Native.OpenUrl(app, url, options))
		return true;
	return base.OpenUrl(app,url,options);
}

You are also required to add the following to add a CFBundleURLSchemes to your info.plist

For Google: com.googleusercontent.apps.YOUR_CLIENT_ID

	<key>CFBundleURLTypes</key>
	<array>
		<dict>
			<key>CFBundleURLSchemes</key>
			<array>
				<string>com.googleusercontent.apps.YOURCLIENTID</string>
			</array>
			<key>CFBundleURLName</key>
			<string>googleLogin</string>
		</dict>
	</array>
	

Android

Google Sign-In on Android

Simple Auth supports the native Google Sign-in for Android.

  1. Add the nuget Clancey.SimpleAuth.Google.Droid

  2. Create OAuth Client Id (Web Application): Link

  3. Create and OAuth Android app: Link

    • Sign your app using the same Keystore
  4. Use both the Web Application ClientID. ClientSecret is not required but reccomended.

  5. Add the following code to your Main Activity

    protected override void OnCreate(Bundle bundle)
    {
    	base.OnCreate(bundle);
    	SimpleAuth.Providers.Google.Init(this.Application);
    	//The rest of your initialize code
    }
    
    protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
    {
       base.OnActivityResult(requestCode, resultCode, data);
    	SimpleAuth.Native.OnActivityResult (requestCode,resultCode,data); 
    }

If you need Cross-Client authentication pass your ServerClientId into the google api

var api = new GoogleApi("google","client_id"){
	ServerClientId = "server_client_id""
};
var account = await api.Authenticate ();
var serverToken = account.UserData ["ServerToken"];

Troubleshooting

If you get: Unable to find explicit activity class {com.google.android.gms.auth.api.signin.internal.SignInHubActivity}; have you declared this activity in your AndroidManifest.xml?

Add the following to your AndroidManifest.xml

<activity android:name="com.google.android.gms.auth.api.signin.internal.SignInHubActivity"
		android:screenOrientation="portrait"
		android:windowSoftInputMode="stateAlwaysHidden|adjustPan" />
	</application>

Status Code 12501 (unknown) Your app signing or tokens are invalid

  1. Check your app is signed with the same KeyStore noted in for your android app Link
  2. Regenerate new OAuth 2 Client id, create the WebApplication kind.

Native Facebook for Android

Simple Auth supports the native Facebook SDK for Android.

  1. Add the nuget Clancey.SimpleAuth.Facebook.Droid

  2. Create an Android App: Link

  3. Add the following to your String.xml in Resources/values. If your appId was 1066763793431980

    <string name="facebook_app_id">1066763793431980</string>
    <string name="fb_login_protocol_scheme">fb1066763793431980</string>
    
  4. Add a meta-data element to the application element:

    [assembly: MetaData("com.facebook.sdk.ApplicationId", Value = "@string/facebook_app_id")]
    
  5. Add FacebookActivity to your AndroidManifest.xml:

    <activity android:name="com.facebook.FacebookActivity"
          android:configChanges=
                 "keyboard|keyboardHidden|screenLayout|screenSize|orientation"
          android:label="@string/app_name" />          
    <activity
        android:name="com.facebook.CustomTabActivity"
        android:exported="true">
        <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="@string/fb_login_protocol_scheme" />
        </intent-filter>
    </activity>
    
  6. Add the following code to your Main Activity

    protected override void OnCreate(Bundle bundle)
    {
    	base.OnCreate(bundle);
    	SimpleAuth.Providers.Google.Init(this.Application);
    	//The rest of your initialize code
    }
    
    protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
    {
       base.OnActivityResult(requestCode, resultCode, data);
    	Native.OnActivityResult (requestCode,resultCode,data); 
    }

CustomTabs for Android

SimpleAuth supports using Custom Tabs for authorization.

  1. Add the nuget Clancey.SimpleAuth.Droid.CustomTabs

  2. In your Droid project, create a subclass of SimpleAuthCallbackActivity to handle your url scheme, replacing the value of DataScheme with the scheme you used for the redirectUrl parameter of the Api constructor

    [Activity(NoHistory = true, LaunchMode = Android.Content.PM.LaunchMode.SingleTop)]
    [IntentFilter(new [] { Intent.ActionView},
        Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable},
        DataScheme = "YOUR CUSTOM SCHEME")]
    public class MyCallbackActivity : SimpleAuthCallbackActivity
    {
    }

.Net Core

You will need to implement an AuthStorage

using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Linq;

namespace SimpleAuth
{
	public class AuthStorage : IAuthStorage
	{
		private const int Keysize = 128;
		private const int DerivationIterations = 1000;

		public static string EncryptString(string plainText, string passPhrase)
		{
			var saltStringBytes = Generate256BitsOfRandomEntropy();
			var ivStringBytes = Generate256BitsOfRandomEntropy();
			var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
			using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
			{
				var keyBytes = password.GetBytes(Keysize / 8);
				using (var symmetricKey = new RijndaelManaged())
				{
					symmetricKey.BlockSize = Keysize;
					symmetricKey.Mode = CipherMode.CBC;
					symmetricKey.Padding = PaddingMode.PKCS7;
					using (var encryptor = symmetricKey.CreateEncryptor(keyBytes, ivStringBytes))
					{
						using (var memoryStream = new MemoryStream())
						{
							using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
							{
								cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
								cryptoStream.FlushFinalBlock();
								// Create the final bytes as a concatenation of the random salt bytes, the random iv bytes and the cipher bytes.
								var cipherTextBytes = saltStringBytes;
								cipherTextBytes = cipherTextBytes.Concat(ivStringBytes).ToArray();
								cipherTextBytes = cipherTextBytes.Concat(memoryStream.ToArray()).ToArray();
								memoryStream.Close();
								cryptoStream.Close();
								return Convert.ToBase64String(cipherTextBytes);
							}
						}
					}
				}
			}
		}

		public static string DecryptString(string cipherText, string passPhrase)
		{
			var cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherText);
			var saltStringBytes = cipherTextBytesWithSaltAndIv.Take(Keysize / 8).ToArray();
			var ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize / 8).Take(Keysize / 8).ToArray();
			var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize / 8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize / 8) * 2)).ToArray();

			using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
			{
				var keyBytes = password.GetBytes(Keysize / 8);
				using (var symmetricKey = new RijndaelManaged())
				{
					symmetricKey.BlockSize = Keysize;
					symmetricKey.Mode = CipherMode.CBC;
					symmetricKey.Padding = PaddingMode.PKCS7;
					using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, ivStringBytes))
					{
						using (var memoryStream = new MemoryStream(cipherTextBytes))
						{
							using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
							{
								var plainTextBytes = new byte[cipherTextBytes.Length];
								var decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
								memoryStream.Close();
								cryptoStream.Close();
								return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
							}
						}
					}
				}
			}
		}

		private static byte[] Generate256BitsOfRandomEntropy()
		{
			var randomBytes = new byte[16];
			using (var rngCsp = new RNGCryptoServiceProvider())
			{
				rngCsp.GetBytes(randomBytes);
			}
			return randomBytes;
		}

		static string CalculateMD5Hash(string input)
		{
			var md5 = MD5.Create();

			var inputBytes = Encoding.ASCII.GetBytes(input);
			var hash = md5.ComputeHash(inputBytes);
			var sb = new StringBuilder();

			for (int i = 0; i < hash.Length; i++)
			{
				sb.Append(hash[i].ToString("X2"));
			}

			return sb.ToString();

		}

		public void SetSecured(string identifier, string value, string clientId, string clientSecret, string sharedGroup)
		{
			var key = $"{clientId}-{identifier}-{clientId}-{sharedGroup}";
			var newKey = CalculateMD5Hash(key);
			var encrypted = EncryptString(value, clientSecret);
			Plugin.Settings.CrossSettings.Current.AddOrUpdateValue(newKey, encrypted);
		}

		public string GetSecured(string identifier, string clientId, string clientSecret, string sharedGroup)
		{
			try
			{
				var key = $"{clientId}-{identifier}-{clientId}-{sharedGroup}";
				var newKey = CalculateMD5Hash(key);
				var cryptText = Plugin.Settings.CrossSettings.Current.GetValueOrDefault(newKey, "");
				return DecryptString(cryptText, clientSecret);
			}
			catch (Exception ex)
			{
				//Console.WriteLine(ex);
			}
			return null;
		}
	}
}

For console apps, you will also need to implement the Authenticators:

Basic Auth

using System;
using System.Security;
using System.Threading.Tasks;
namespace SimpleAuth
{
    public class BasicAuthController
    {
        readonly IBasicAuthenicator authenticator;

        public BasicAuthController(IBasicAuthenicator authenticator)
        {
            this.authenticator = authenticator;
        }


        public async Task<Tuple<string, string>> GetCredentials(string title, string details = "")
        {
            try
            {
                Console.WriteLine("******************");
                Console.WriteLine(title);
                Console.WriteLine(details);
                Console.WriteLine("******************");
                Console.WriteLine("Enter Username:");
                var username = Console.ReadLine();
                Console.WriteLine("Enter Password:");
                var password = GetPassword();

                var result = new Tuple<string, string>(username, password);
                try
                {
                    bool success = false;
                    var basic = authenticator;
                    if (basic != null)
                    {
                        success = await basic.VerifyCredentials(result.Item1, result.Item2);
                    }
                    if (!success)
                        throw new Exception("Invalid Credentials");
                }
                catch (Exception ex)
                {
                    result = await GetCredentials(title, $"Error: {ex.Message}");
                }
                return result;
            }
            catch (TaskCanceledException)
            {
                authenticator.OnCancelled();
                return null;
            }
        }
        public string GetPassword()
        {
            var pwd = "";
            while (true)
            {
                ConsoleKeyInfo i = Console.ReadKey(true);
                if (i.Key == ConsoleKey.Enter)
                {
                    break;
                }
                else if (i.Key == ConsoleKey.Backspace)
                {
                    if (pwd.Length > 0)
                    {
                        pwd.Remove(pwd.Length - 1);
                        Console.Write("\b \b");
                    }
                }
                else
                {
                    pwd += (i.KeyChar);
                    Console.Write("*");
                }
            }
            return pwd;
        }
    }
}

Web Authenticator

using System;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace SimpleAuth
{
    public class WebAuthenticatorController
    {
        readonly WebAuthenticator authenticator;

        public WebAuthenticatorController(WebAuthenticator authenticator)
        {
            this.authenticator = authenticator;
        }


        public async Task GetCredentials(string title, string details = "")
        {
            try
            {
                var url = await authenticator.GetInitialUrl();
                Console.WriteLine("******************");
                Console.WriteLine(title);
                Console.WriteLine(details);
                Console.WriteLine($"Launching Url: \"{url}\"");
                Console.WriteLine("******************");
                Console.WriteLine("Paste the Redirected URL Here:");
                OpenBrowser(url);
                var username = Console.ReadLine();

                try
                {
                    bool success = false;
                    var basic = authenticator;
                    if (basic != null)
                    {
                        success = basic.CheckUrl(new Uri(username), null);
                    }
                    if (!success)
                        throw new Exception("Invalid Credentials");
                }
                catch (Exception ex)
                {
                    await GetCredentials(title, $"Error: {ex.Message}");
                }
            }
            catch (TaskCanceledException)
            {
                authenticator.OnCancelled();
            }
        }

        public static void OpenBrowser(Uri uri)
        {
            OpenBrowser(uri.AbsoluteUri);
        }

        public static void OpenBrowser(string url)
        {
            try
            {
                Process.Start(url);
            }
            catch
            {
                // hack because of this: https://github.com/dotnet/corefx/issues/10361
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    url = url.Replace("&", "^&");
                    Process.Start(new ProcessStartInfo("cmd", $"/c start {url}") { CreateNoWindow = true });
                }
                else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                {
                    Process.Start("xdg-open", url);
                }
                else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
                {
                    Process.Start("open", url);
                }
                else
                {
                    throw;
                }
            }
        }
    }
}
Comments
  • A task was cancelled

    A task was cancelled

    I have a problem with login with google. Exception throws when i am trying to login Exception: "A task was cancelled" after i try call

    var account = await AuthAsync(google);
    

    I have tried to check example. But It throws the same exception.

    opened by Fr2eman 32
  • Add support for Android Target SDK API 23 (currently Google Sign In crashes)

    Add support for Android Target SDK API 23 (currently Google Sign In crashes)

    If you target API 23+ the app must prompt the user for GetAccounts permission:

    https://blog.xamarin.com/requesting-runtime-permissions-in-android-marshmallow/

    We need to add a call to CheckSelfPermission.

    Without that, I am finding that Authenticate() throws an exception, which I catch, but even so my app terminates with:

    System.InvalidOperationException: An attempt was made to transition a task to a final state when it had already completed.
      at System.Threading.Tasks.TaskCompletionSource`1[TResult].SetResult (TResult result) [0x0000c] in /Users/builder/data/lanes/4468/f913a78a/source/mono/mcs/class/referencesource/mscorlib/system/threading/Tasks/TaskCompletionSource.cs:322
      at Android.Gms.Extensions.GoogleApiClientExtensions+<BuildAndConnectAsync>c__AnonStorey0.<>m__0 (Android.OS.Bundle hint) [0x00000] in <1db671c6182d42a7b22c48ed6b33a584>:0
      at Android.Gms.Common.Apis.GoogleApiClientConnectionCallbacksImpl.OnConnected (Android.OS.Bundle bundle) [0x0000d] in <1db671c6182d42a7b22c48ed6b33a584>:0
      at Android.Gms.Common.Apis.GoogleApiClient+IConnectionCallbacksInvoker.n_OnConnected_Landroid_os_Bundle_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_connectionHint) [0x00011] in <1db671c6182d42a7b22c48ed6b33a584>:0
      at at (wrapper dynamic-method) System.Object:a6b03050-593a-4ddc-9bdf-441125fda0bf (intptr,intptr,intptr)
    
    opened by trevoriancox 25
  • Google Login Bug

    Google Login Bug

    When I use google login in my Android app, while this code executes : var user = await api.Get("https://www.googleapis.com/oauth2/v1/userinfo?alt=json"); My screen flashes 3 times and OnAppearing method gets called 3 times. After that I'm signed in normally. Is this normal behaviour ? Thanks in advance.

    opened by goranmedic 17
  • Correctly handle re-authentication

    Correctly handle re-authentication

    This PR resolves issues I was experiencing using OAuthApi with respect to re-authentication. Note that I am not 💯 confident that these changes are perfect, and definitely need a review.

    The changes are:

    • re-create the authenticator in the CreateAuthenticator method (unless the constructor taking an authenticator is used). Without this, the existing authenticator would return its cached tokenTask, effectively meaning the token was cached and replayed indefinitely
    • call PerformAuthenticate instead of Authenticate from RefreshToken. During re-authentication, RefreshToken is called in response to an Authenticate call, so calling Authenticate again just returns the cached Task representing the initial call to Authenticate. Hence, the code ended up awaiting...itself :)
    • after a successful call to RefreshAccount, reassign the account data to the account variable. Without this, it was still looking at the old account data.

    My biggest concern is probably the first point. I didn't know how to solve this more elegantly than using a Func<WebAuthenticator> to re-create the authenticator. I don't really understand the purpose of the ctor that takes an authenticator because then the authenticator would never be reset, even upon expiry of the token.

    opened by kentcb 11
  • TwitterApi - Null Reference exception

    TwitterApi - Null Reference exception

    Just installed the latest 1.0.19 (for using the fix of cookie per api call), but fond my old code doesn't work on calling the Authenticate method of TwitterApi:

    at SimpleAuth.OAuthApi+d__31.MoveNext () [0x00042] in :0 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/3412/3cf8aaed/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00047] in /Users/builder/data/lanes/3412/3cf8aaed/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:187 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in /Users/builder/data/lanes/3412/3cf8aaed/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:156 at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in /Users/builder/data/lanes/3412/3cf8aaed/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:128 at System.Runtime.CompilerServices.TaskAwaiter1[TResult].GetResult () [0x00000] in /Users/builder/data/lanes/3412/3cf8aaed/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:357 at SimpleAuth.AuthenticatedApi+<Authenticate>d__15.MoveNext () [0x000c1] in <filename unknown>:0 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/3412/3cf8aaed/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00047] in /Users/builder/data/lanes/3412/3cf8aaed/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:187 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in /Users/builder/data/lanes/3412/3cf8aaed/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:156 at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in /Users/builder/data/lanes/3412/3cf8aaed/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:128 at System.Runtime.CompilerServices.TaskAwaiter1[TResult].GetResult () [0x00000] in /Users/builder/data/lanes/3412/3cf8aaed/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:357

    opened by jzhouw 9
  • Error processing method: CheckNewGooglePlayServices

    Error processing method: CheckNewGooglePlayServices

    Since changing Target Framework to use Android 8.0 (Oreo), I'm getting the following error on release builds:

    7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: The "LinkAssemblies" task failed unexpectedly. 7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: Mono.Linker.MarkException: Error processing method: 'System.Void SimpleAuth.Providers.Google/GoogleSignInProvider::CheckNewGooglePlayServices(Android.App.Activity)' in assembly: 'SimpleAuth.Google.Droid.dll' ---> Mono.Cecil.ResolutionException: Failed to resolve System.Boolean Android.Gms.Common.Zze::IsUserResolvableError(System.Int32) 7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Mono.Linker.Steps.MarkStep.HandleUnresolvedMethod(MethodReference reference) 7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Mono.Linker.Steps.MarkStep.MarkMethod(MethodReference reference) 7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Mono.Linker.Steps.MarkStep.MarkInstruction(Instruction instruction) 7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Mono.Linker.Steps.MarkStep.MarkMethodBody(MethodBody body) 7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Mono.Linker.Steps.MarkStep.ProcessMethod(MethodDefinition method) 7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Mono.Linker.Steps.MarkStep.ProcessQueue() 7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: --- End of inner exception stack trace --- 7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Mono.Linker.Steps.MarkStep.ProcessQueue() 7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Mono.Linker.Steps.MarkStep.ProcessEntireQueue() 7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Mono.Linker.Steps.MarkStep.Process() 7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Mono.Linker.Steps.MarkStep.Process(LinkContext context) 7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Mono.Linker.Pipeline.Process(LinkContext context) 7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at MonoDroid.Tuner.Linker.Process(LinkerOptions options, LinkContext& context) 7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Xamarin.Android.Tasks.LinkAssemblies.Execute(DirectoryAssemblyResolver res) 7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Xamarin.Android.Tasks.LinkAssemblies.Execute() 7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute() 7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Microsoft.Build.BackEnd.TaskBuilder.d__26.MoveNext()

    I'm using the following versions: Clancey.SimpleAuth 1.0.41 Clancey.SimpleAuth.Google.Droid 1.0.9

    (Not using version 1.0.47 of Clancey.SimpleAuth because I'm still using PCL's.)

    My linking is set to "Sdk Assemblies Only".

    Note that I still get the error even if I include "SimpleAuth;SimpleAuth.Google.Droid" in the "Skip linking assemblies" section.

    (It compiles fine if I change the "Linking" to "None", but this is obviously not ideal.)

    opened by RalphJacobson 8
  • Java.Security.UnrecoverableKeyException: no match

    Java.Security.UnrecoverableKeyException: no match

    Hi, I'm using your library for authentication with different social media. In the case of Facebook, I'll do it with a webview. When I use the FacebookApi and show the webview. The following error appears:

    screenshot_20171110-173122

    The error that appears in the console is the following:

    Java.Security.UnrecoverableKeyException: no match
      at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <896ad1d315ca4ba7b117efb8dacaedcf>:0 
      at Java.Interop.JniEnvironment+InstanceMethods.CallNonvirtualObjectMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniObjectReference type, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x00089] in <7cfbebb561c54efc9010b018c0846c7e>:0 
      at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeNonvirtualObjectMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x0001f] in <7cfbebb561c54efc9010b018c0846c7e>:0 
      at Java.Security.KeyStore.GetEntry (System.String alias, Java.Security.KeyStore+IProtectionParameter protParam) [0x00050] in <9ef29c909d7e4606a46b131129da3975>:0 
      at SimpleAuth.AuthStorage.GetSecured (System.String id, System.String clientId, System.String service, System.String sharedGroup) [0x00048] in C:\Projects\SimpleAuth\src\SimpleAuth.Droid\AuthStorage.cs:33 
      at SimpleAuth.AuthenticatedApi.GetAccount[T] (System.String identifier) [0x00002] in C:\Projects\SimpleAuth\src\SimpleAuth\Api\AuthenticatedApi.cs:88 
      --- End of managed Java.Security.UnrecoverableKeyException stack trace ---
    java.security.UnrecoverableKeyException: no match
    	at com.android.org.bouncycastle.jcajce.provider.keystore.bc.BcKeyStoreSpi$StoreEntry.getObject(BcKeyStoreSpi.java:315)
    	at com.android.org.bouncycastle.jcajce.provider.keystore.bc.BcKeyStoreSpi.engineGetKey(BcKeyStoreSpi.java:610)
    	at java.security.KeyStoreSpi.engineGetEntry(KeyStoreSpi.java:474)
    	at java.security.KeyStore.getEntry(KeyStore.java:1560)
    	at md5b60ffeb829f638581ab2bb9b1a7f4f3f.InnerGestureListener.n_onSingleTapUp(Native Method)
    	at md5b60ffeb829f638581ab2bb9b1a7f4f3f.InnerGestureListener.onSingleTapUp(InnerGestureListener.java:79)
    	at android.view.GestureDetector.onTouchEvent(GestureDetector.java:640)
    	at md5b60ffeb829f638581ab2bb9b1a7f4f3f.Platform_DefaultRenderer.n_dispatchTouchEvent(Native Method)
    	at md5b60ffeb829f638581ab2bb9b1a7f4f3f.Platform_DefaultRenderer.dispatchTouchEvent(Platform_DefaultRenderer.java:54)
    	at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2961)
    	at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2650)
    	at md5b60ffeb829f638581ab2bb9b1a7f4f3f.Platform_DefaultRenderer.n_dispatchTouchEvent(Native Method)
    	at md5b60ffeb829f638581ab2bb9b1a7f4f3f.Platform_DefaultRenderer.dispatchTouchEvent(Platform_DefaultRenderer.java:54)
    

    How can I solve this error?

    opened by sergio11 8
  • Fix Dropbox Authentication -999 Error

    Fix Dropbox Authentication -999 Error

    Ignore the "NSURLErrorDomain -999" authentication error with Dropbox. Issue #76.

    James - it looks like the files from my previous pull (4871dac) might be include in the pull as well. The only file I changed in this pull is WebAuthenticator.cs.

    When do you think the next NuGet version with the changes from the last, and this pull be built and made available from Nuget.org?

    Thanks

    Allan

    opened by allan-chin 7
  • Improved PCL support

    Improved PCL support

    Hi Again!

    I was trying to use the current Nugert version of SimpleAuth (1.18) with my project and just add this DropBox provider in the source in a PCL common auth lib. However, doing that proved problematic, as it compiled against the SimpleAuth\System.Web.HttpUtility which ParseQueryString (HttpValueCollection) has no BCL equivalent...

    Hence Changed its signature to match BCL and added TypeForward attribute for better PCL support

    opened by superlloyd 7
  • NSURLErrorDomain -999 with DropBox

    NSURLErrorDomain -999 with DropBox

    Trying to connect to DropBox from Xamarin.Mac returns an exception. Same Dropbox-account with Windows works fine. Any ideas?

    System.Exception: The operation couldn’t be completed. (NSURLErrorDomain error -999.)
      at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Library/Frameworks/Xamarin.Mac.framework/Versions/4.4.1.193/src/Xamarin.Mac/mcs/class/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:152
      at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00037] in /Library/Frameworks/Xamarin.Mac.framework/Versions/4.4.1.193/src/Xamarin.Mac/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:187
      at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in /Library/Frameworks/Xamarin.Mac.framework/Versions/4.4.1.193/src/Xamarin.Mac/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:156
      at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in /Library/Frameworks/Xamarin.Mac.framework/Versions/4.4.1.193/src/Xamarin.Mac/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:128
      at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult () [0x00000] in /Library/Frameworks/Xamarin.Mac.framework/Versions/4.4.1.193/src/Xamarin.Mac/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:357
      at SimpleAuth.OAuthApi+<PerformAuthenticate>d__32.MoveNext () [0x00392] in SimpleAuth-master/src/SimpleAuth/OAuthApi.cs:164
    
    opened by TomQv 6
  • Xamarin.Forms iOS login with different user.

    Xamarin.Forms iOS login with different user.

    I've implemented Facebook login to XF project. Login works good. I do logout:

     SocialAuthApi = new FacebookApi("facebook", AppConstants.FacebookClientId, AppConstants.FacebookClientSecret);
     SocialAuthApi.ResetData();
     SocialAuthApi.Logout();
    
    

    And after that I want to login by another user, but I can't do bcouz previous user was saved and facebook propose me log in with the same user. How I can log in by different user?

    opened by ghost 6
  • Bump Newtonsoft.Json from 10.0.3 to 13.0.2 in /src/SimpleAuth.UWP

    Bump Newtonsoft.Json from 10.0.3 to 13.0.2 in /src/SimpleAuth.UWP

    Bumps Newtonsoft.Json from 10.0.3 to 13.0.2.

    Release notes

    Sourced from Newtonsoft.Json's releases.

    13.0.2

    • New feature - Add support for DateOnly and TimeOnly
    • New feature - Add UnixDateTimeConverter.AllowPreEpoch property
    • New feature - Add copy constructor to JsonSerializerSettings
    • New feature - Add JsonCloneSettings with property to disable copying annotations
    • Change - Add nullable annotation to JToken.ToObject(Type, JsonSerializer)
    • Change - Reduced allocations by reusing boxed values
    • Fix - Fixed MaxDepth when used with ToObject inside of a JsonConverter
    • Fix - Fixed deserializing mismatched JToken types in properties
    • Fix - Fixed merging enumerable content and validate content
    • Fix - Fixed using $type with arrays of more than two dimensions
    • Fix - Fixed rare race condition in name table when deserializing on device with ARM processors
    • Fix - Fixed deserializing via constructor with ignored base type properties
    • Fix - Fixed MaxDepth not being used with ISerializable deserialization

    13.0.1

    • New feature - Add JsonSelectSettings with configuration for a regex timeout
    • Change - Remove portable assemblies from NuGet package
    • Change - JsonReader and JsonSerializer MaxDepth defaults to 64
    • Change - Change InvalidCastException to JsonSerializationException on mismatched JToken
    • Fix - Fixed throwing missing member error on ignored fields
    • Fix - Fixed various nullable annotations
    • Fix - Fixed annotations not being copied when tokens are cloned
    • Fix - Fixed naming strategy not being used when deserializing dictionary enum keys
    • Fix - Fixed serializing nullable struct dictionaries
    • Fix - Fixed JsonWriter.WriteToken to allow null with string token
    • Fix - Fixed missing error when deserializing JToken with a contract type mismatch
    • Fix - Fixed JTokenWriter when writing comment to an object

    12.0.3

    • New feature - Added support for nullable reference types
    • New feature - Added KebabCaseNamingStrategy
    • Change - Package now uses embedded package icon
    • Fix - Fixed bug when merging JToken with itself
    • Fix - Fixed performance of calling ICustomTypeDescriptor.GetProperties
    • Fix - Fixed serializing Enumerable.Empty and empty arrays on .NET Core 3.0
    • Fix - Fixed deserializing some collection types with constructor
    • Fix - Fixed deserializing IImmutableSet to ImmutableHashSet instead of ImmutableSortedSet
    • Fix - Fixed deserializing IImmutableDictionary to ImmutableDictionary instead of ImmutableSortedDictionary
    • Fix - Fixed deserializing into constructors with more than 256 parameters
    • Fix - Fixed hang when deserializing JTokenReader with preceding comment
    • Fix - Fixed JSONPath scanning with nested indexer
    • Fix - Fixed deserializing incomplete JSON object to JObject
    • Fix - Fixed using StringEnumConverter with naming strategy and specified values

    12.0.2

    • New feature - Added MissingMemberHandling to JsonObjectAttribute and JsonObjectContract
    • New feature - Added constructor to JTokenReader to specify initial path
    • New feature - Added JsonProperty.IsRequiredSpecified
    • New feature - Added JsonContract.InternalConverter

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Bump Newtonsoft.Json from 13.0.1 to 13.0.2

    Bump Newtonsoft.Json from 13.0.1 to 13.0.2

    Bumps Newtonsoft.Json from 13.0.1 to 13.0.2.

    Release notes

    Sourced from Newtonsoft.Json's releases.

    13.0.2

    • New feature - Add support for DateOnly and TimeOnly
    • New feature - Add UnixDateTimeConverter.AllowPreEpoch property
    • New feature - Add copy constructor to JsonSerializerSettings
    • New feature - Add JsonCloneSettings with property to disable copying annotations
    • Change - Add nullable annotation to JToken.ToObject(Type, JsonSerializer)
    • Change - Reduced allocations by reusing boxed values
    • Fix - Fixed MaxDepth when used with ToObject inside of a JsonConverter
    • Fix - Fixed deserializing mismatched JToken types in properties
    • Fix - Fixed merging enumerable content and validate content
    • Fix - Fixed using $type with arrays of more than two dimensions
    • Fix - Fixed rare race condition in name table when deserializing on device with ARM processors
    • Fix - Fixed deserializing via constructor with ignored base type properties
    • Fix - Fixed MaxDepth not being used with ISerializable deserialization
    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Login disabled on facebook

    Login disabled on facebook

    My app stop working and is now showing this error on facebook for android. Login disabled", "For your account security, logging in to Facebook from an embedded browser is disabled. You may be able to continue by updating the app you're logging in from and trying again."

    opened by ekeneduru 0
  • Google Sign In crashes on Android 8.0 (documentation issue)

    Google Sign In crashes on Android 8.0 (documentation issue)

    If you follow the SimpleAuth documentation, your app will crash on Android 8.0 with the exception:

    java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation

    The fix is to omit this from AndroidManifest.xml:

    android:screenOrientation="portrait"

    This seems to be a well-known Android 8.0 issue.

    opened by trevoriancox 0
  • Support for hd (domain hint) parameter for Google Sign In / tenant ID for Microsoft sign in

    Support for hd (domain hint) parameter for Google Sign In / tenant ID for Microsoft sign in

    For an enterprise app, we often know the domain that the user is going to sign in with. It's easy with web login to specify e.g. ?hd=github.com. How can we provide that parameter using SimpleAuth?

    Likewise for Microsoft, with MSAL you can specify the Tenant ID to restrict sign in to a specified domain.

    opened by trevoriancox 1
  • Google signin for Flutter windows?

    Google signin for Flutter windows?

    Hi @Clancey, your library seems really promising, and thanks for your hard work for all of us. I was wondering if there is a way to use simpleAuth for Flutter Windows.

    I have tried it but it shows MethodChannel not found. I assume it was because the method channel for Windows was missing. Is there a way we can implement this. Maybe using windows cli commands it can work?

    opened by SahajRana 2
Owner
James Clancey
discord: https://discord.gg/7Ms7ptM
James Clancey
A Dart/Flutter package to perform network calls. It uses Isolates to perform network calls on Dart VM environments and WebWorkers on Web.

ArDriveHTTP ArDriveHTTP is a package to perform network calls for ArDrive Web. It uses Isolates to perform network calls on Dart VM environments and W

AR.IO 2 Dec 15, 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
Bhagavad Gita app using flutter & Bhagavad-Gita-API is A lightweight Node.js based Bhagavad Gita API [An open source rest api on indian Vedic Scripture Shrimad Bhagavad Gita].

Gita Bhagavad Gita flutter app. Download App - Playstore Web Application About Bhagavad Gita app using flutter & Bhagavad-Gita-API is A lightweight No

Ravi Kovind 7 Apr 5, 2022
Call Kit is a prebuilt feature-rich call component, which enables you to build one-on-one and group voice/video calls into your app with only a few lines of code.

Call Kit (ZegoUIKitPrebuiltCall) Call Kit is a prebuilt feature-rich call component, which enables you to build one-on-one and group voice/video calls

ZEGOCLOUD 9 Dec 26, 2022
Flutter tutorial - This is my first Flutter tutorial app. Thanks to The Net Ninja youtube channel for this wonderful tutorial

ninja_id A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if this

null 1 Jun 9, 2022
Techcareer.net Flutter Bootcamp Bitirme Projesi

foodie Techcareer.net Flutter Bootcamp Bitirme Projem olan Foodie, bir yemek sipariş uygulamasıdır. Bu projeyi gerçekleştirirken kullandığım yapılar;

Lütfiye Yaşar 4 Oct 3, 2022
Movie API Use Rest And Restful API

movie_api use rest and restful api The home screen fetches data from the Episodate API and shows a list of popular shows. The details screen and the s

Le Gia Huy 1 Dec 5, 2022
Netflix app UI clone using bloc,Rest API and TMDB for API key

netflix_flutter project_using_bloc packages Used flutter_bloc json_serializable get_it dio A few resources to get you started if this is your first Fl

Pranav Pv 16 Nov 25, 2022
FLutter Api Integration - Flutter Rest API Integration

Flutter_Rest_Api_integration Flutter_Rest_Api_integration. Preview How To Use To

Rahul Ranjan Singh 0 Feb 17, 2022
In this video we will learn how to Create CRUD Rest API for our Flutter application using NODEJS API.

Flutter CRUD Using NodeJS API In this video we will learn how to Create CRUD Rest API for our Flutter application using NODEJS API. ?? Packages Used h

SnippetCoder 14 Dec 30, 2022
A package help you to make api call and handle error faster, also you can check for internet before call api.

http_solver ##not for production use, only for learning purpose. A package help you to make api call and handle error faster, also you can check for i

Abdelrahman Saed 1 Jun 18, 2020
The easiest way to create your animated splash screen in a fully customizable way.

Animated Splash Screen Check it out at Pub.Dev Do it your way Assets image Custom Widget Url image IconData Or just change PageTransition and/or Splas

Clean Code 104 Nov 10, 2022
Flutter-for-Wordpress-App - Cross platform wordpress news app built with Flutter and WP REST API

Flutter for Wordpress A flutter app for a wordpress websites with clean and elegant design. This app is available in free and pro version. You can cho

Madhav Poudel 243 Dec 23, 2022
This App Using 2 Rest APi One for Login & SignUP and other for Weather

Requirnment A Flutter app where user can signup using Api endpoint and login using Api endpoint. And after login user go to the dashboard where user c

Md Enam Ahmed Chowdhury 3 Mar 14, 2022
This example uses a ScrollView, JSON Rest API, Navigation, Alert Pop Up, Progress Indicator, Globals, Images in a shared asset folder, and 100% Shared Code

This example uses a ScrollView, JSON Rest API, Navigation, Alert Pop Up, Progress Indicator, Globals, Images in a shared asset folder, and 100% Shared Code. Now with the ability to login with FaceID, TouchID, and Fingerprint Reader on Android.

Rody Davis 672 Jan 6, 2023
A Rick and Morty Character Wiki, build in Flutter with Api Rest integration.

Rick and Morty Character Wiki This is an app build in Flutter that loads a list of characters (from the serie Rick and Morty) and his info, and displa

Jessica Aidyl 3 Jul 27, 2022
Flutter Rest API using Http and Provider State.

Getting Started This project is a starting point for a Flutter application. A few resources to get you started if this is your first Flutter project:

Joshua Jeremia 2 Aug 31, 2022