I wanted to add some more detail about the implementation we did in part 2 and limitations.
There are disadvantages to using an embedded browser for authentication in Xamarin. Mainly, it’s isolated from the native browser. So if a user is already logged into Facebook on his phone, he’ll still have renter his credentials in your siloed browser. There are also some security concerns.
However, I’ve read that latest Xamarin.Forms updates utilize a more modern WebView making the approach a bit more appealing - such as shared cookies. As I demonstrated previously it’s also quite easy :)
Utilizing the Native Browser for Authentication
To overcome the limitations of the embedded Webview, we can replicate the same auth behavior with the native browser. To get a callback, we can utilize Xamarin Forms Deeplinks.
This is a more secure way of doing auth on mobile. We generally follow the same steps as part 2 except for a few minor tweaks.
1. Use the native browser instead of a WebView
Instead of using an embedded browser, we send the user to open the Auth URL in the device’s native browser instead. We can use the Device.OpenUri
call.
// URL the is the one we used as the origin of our browser above
Device.OpenUri(new Uri(URL, UriKind.Absolute));
2. Update the Callback URL to open our app from the native browser.
We can have the callback URL reopen our app using deeplinks. For example, let’s assume our app had an URL like \\mail?code=xyz
, and that prompted the user to open the app like this:
That’d be fine. We can still do the same steps as above. However, we need to do two extra things to allow our app to be opened by the URL.
-
Let the device know that we can open our app with this interal app uri. You can read how to set that up here as deeplinks. Also be sure to update the callback URL in your auth providers website, so the native browser prompts redirects to your app instead of
example.com
. -
In our app, we need to listen to when an App is opened through an internal URI. We can do this by overriding an
OnAppLinkRecieved
handler.
On iOS, in the AppDelegate.cs
we can override the OpenURL
method.
public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options)
{
App myApp = App.Current as ActionInbox.App;
if (null != myApp && null != url)
{
myApp.OnAppLinkRequestReceived(new Uri(url.AbsoluteString));
}
return true;
}
And in our App.CS add the following:
public new void OnAppLinkRequestReceived(Uri uri)
{
var data = uri.ToString().ToLowerInvariant();
Debug.WriteLine("Got called as:", data);
//Extract the Code Token
//Exchange the code for an access token
//Navigate based on id here.
base.OnAppLinkRequestReceived(uri);
}
3. Isolate the logic we did above and exchange the code for our access code.
We continue to make the POST request for the access token and redirect the user to the right page as needed. Just add your logic to the if statement above and redirect the user to the right page.
You can choose to create an intermediary page, redirect to that, and then do the access token logic in there so the user knows his page is loading.
Conclusion
That’s all. No extra libraries. No fuss. You can, of course, choose to skip all of the implementation steps and use Xamarin.Auth instead. Which I recommend by the way - probably more secure too.
Here’s the link to my sample code with the embedded browser login.
I hope from this series you now know how authentication works behind the scenes and feel more empowered than I was when I got started with OAuth.