It would be great to use a page renderer in each platform and handle all in that renderer.
This already works in a facebook login and page renderer I created. Separate page renderers in iOS and Android and both work for FaceBook authentication.
Here’s the page renderer, hopefully someone can make head or tail out of that. I’ve added code I’ve tried for Auth0 using the Auth0Client as well as suggestions commented out. I’m sure someone at Auth0 could adapt this to make something work in a Xamarin.Form SHARED project…
using System;
using Android.App;
using Xamarin.Forms.Platform.Android;
using Xamarin.Auth;
using MyCompany.Views;
using MyCompany.Droid;
using Xamarin.Forms;
using System.Threading.Tasks;
using System.Net.Http;
using Newtonsoft.Json;
using MyCompany.Authentication;
using Auth0.OidcClient;
[assembly: ExportRenderer(typeof(LoginPageAO), typeof(LoginPageRendererAO))]
namespace MyCompany.Droid
{
public class LoginPageRendererAO : Xamarin.Auth.XamarinForms.XamarinAndroid.AuthenticatorPageRenderer
{
protected override async void OnElementChanged(ElementChangedEventArgs<Page> e)
{
var client = new Auth0Client(new Auth0ClientOptions
{
Domain = "MyCompany.auth0.com",
ClientId = "abcdefg..."
});
var loginResult = await client.LoginAsync();
//OR Use the OAuth2Authenticator and handle the "completed" and "error" methods
//We would need a return of which provider the user chose so that user details can be retrieved from that provider with the given access credentials
//_authenticator = new OAuth2Authenticator(
//clientId: "abcdefg...", // your OAuth2 client id
//scope: "", // the scopes for the particular API you're accessing, delimited by "+" symbols
//authorizeUrl: new Uri("https://MyCompany.auth0.com/authorize"), // the auth URL for the service
//redirectUrl: new Uri("com.MyCompany.MyCompany://MyCompany")
//) // the redirect URL for the service
//{
// AllowCancel = true,
//};
//_authority = "AO";
//_authenticator.Completed += Authentication_Completed;
//_authenticator.Error += Authentication_Error;
//var intent = auth.GetUI(activity);
//activity.StartActivity(intent);
}
private void OnAuthenticationCompleted(object sender, AuthenticatorCompletedEventArgs e)
{
if (e.IsAuthenticated)
{
var accessToken = e.Account.Properties["access_token"];
//NOTE: Using Auth0, we'd need to know what provider the client chose so as to get user details unless this is already retrieved
//OPTION 1 (I've not included all the FB client and service code)
var facebookClient = new FacebookClient();
var facebookService = new FacebookService(facebookClient);
var getAccountTask = facebookService.GetAccountAsync(accessToken);
//getAccountTask.Wait();
//Task.WaitAll(getAccountTask);
//var account = getAccountTask.Result;
//Settings.UserId = account.Id;
//OPTION 2
//Task<string> s = GetUserIDAsync(accessToken);
//Task.WaitAll(s);
//s.ContinueWith(null);
//string s = GetUserID(accessToken);
//OPTION 3
//JObject obj = new JObject();
//var request = new OAuth2Request("GET", new Uri("https://graph.facebook.com/me"), null, e.Account);
//request.GetResponseAsync().ContinueWith(t => {
// t.Wait();
// if (t.IsFaulted)
// {
// //App.UnSuccessfulLoginAction.Invoke();
// }
// else
// {
// obj = JObject.Parse(t.Result.GetResponseText());
// string userId = (string)obj["id"];
// Settings.UserId = userId;
// }
//});
//This will hide the login screen and start the MainPage
App.SuccessfulLoginAction.Invoke();
}
else
{
// The user is not authenticated
}
}
private void OnAuthenticationFailed(object sender, AuthenticatorErrorEventArgs e)
{
//this.Dispose();
}
public string GetUserID(string accessToken)
{
var httpClient = new HttpClient();
var userIdjson = httpClient.GetStringAsync($"https://graph.facebook.com/v2.12/me?fields=id&access_token=" + accessToken);
return userIdjson.ToString();
}
public async Task<string> GetUserIDAsync(string accessToken)
{
var httpClient = new HttpClient();
var userIdjson = await httpClient.GetStringAsync($"https://graph.facebook.com/v2.12/me?fields=id,name&access_token=" + accessToken);
var userId = JsonConvert.DeserializeObject(userIdjson);
return userId.ToString();
}
}
}