WebAuth login Add-on
An Add-on that opens an OAuth 2.0 authorization URL built by the app in an authentication-only browser session provided by the platform, and returns the redirect callback URL and query parameters that come back after authentication finishes. It follows the external user-agent approach of RFC 8252, the OAuth 2.0 specification for native apps, and you use it to get credentials for combinations of external authentication providers and OSs that have no dedicated login Add-on.
The Add-on does not interpret or verify OAuth parameters. The app is responsible for interpreting OAuth values such as PKCE, state, and nonce, and for checking that the redirect URI matches.
The authentication session feature that each platform uses is as follows.
- iOS, macOS:
ASWebAuthenticationSession - Android: Chrome Custom Tabs
- Windows: Default browser and loopback HTTP listener
Module information
- Package:
com.com2usplatform.hiveaxyl.auth.addon.webauth - Interfaces:
IExternalUserAgent,IWindowsLoopbackAgent - Entry class:
WebAuthSessionPlugin - Namespace:
Hive.Axyl.Auth.Addon.WebAuth - Registration method:
AddWebAuth() - Supported platforms: Android, Windows, iOS, macOS
- Minimum requirements: Android API 29+, iOS 17+, macOS 15+, Unity 6000.0+
Prerequisites
You must prepare a redirect URI for each platform so that the app can receive the redirect callback after the external authentication provider finishes authentication. For how to prepare it, see Prepare the redirect URI.
Registration and retrieval
Register the Add-on in the registration step of HiveBootstrap.Initialize, and then retrieve IExternalUserAgent with HiveCore.TryResolve<T>(). The registered object is WebAuthSessionPlugin.
using Hive.Axyl.Auth;
using Hive.Axyl.Auth.Addon.WebAuth;
using Hive.Axyl.Core;
using Hive.Axyl.Core.Unity; // HiveBootstrap
HiveBootstrap.Initialize(config, builder =>
{
builder.AddAuth()
.AddToken()
.AddWebAuth();
});
if (HiveCore.TryResolve<IExternalUserAgent>(out var webAuth))
{
// Code that runs only in builds for supported platforms
}
Not registered in the Unity Editor
This Add-on is registered only in players built for Android, Windows, iOS, or macOS. In the Unity Editor, it is not registered even if the platform matches, so using HiveCore.Resolve<T>() throws RegistrationNotFoundException. Always check with TryResolve<T>() before you use it.
For the package installation and registration procedure, see Install and initialize the module.
Method summary
Asynchronous methods take CancellationToken ct = default as the last parameter. For the calling conventions, see Call context.
| Interface or class | Member | Description |
|---|---|---|
IExternalUserAgent | OpenAsync() | Opens the authorization URL in an authentication-only browser session and receives the redirect callback. |
IExternalUserAgent | CancelCurrentSession() | Cancels the in-progress session from code. |
WebAuthSessionPlugin | WindowsLoopback | Gets the Windows-only loopback agent. |
IWindowsLoopbackAgent | AllocateLoopbackRedirectUriAsync() | Reserves a loopback redirect URI and an HTTP listener on Windows. |
IExternalUserAgent
An interface that opens an authentication-only browser session and returns the redirect callback delivered by the platform.
OpenAsync
Opens the authorization URL built by the app in an authentication-only browser session and waits until the platform delivers the redirect callback. When it receives the callback, it returns the original callback URL and the query parameters.
Only one session proceeds at a time. If you call it again while a session is in progress, it leaves the in-progress session as is and immediately returns a Failure whose Code is FailedPrecondition.
- Request: OpenRequest
- Response: OpenResponse
Result cases — ExternalUserAgentServiceOpenResult
| Result case | Wire code | Description |
|---|---|---|
Success | — | The redirect callback has been received. Data contains the callback URL and query parameters. |
UserCanceled | user_canceled | The app user closed the authentication screen by closing the window or by selecting back or cancel. You can prompt the app user to try again. On Windows, this result is not returned because the app user closing the browser is not detected. |
UnknownOutcome | UNKNOWN | A new result unknown to this SDK version. |
Failure | FAILURE | The call could not be completed. Check the cause with the HiveError in Problem. This also applies when the platform is not supported or the native callback could not be processed. |
UserCanceled implements IUserCanceledOutcome.
User cancellation and code cancellation are different
If the app user closes the authentication screen, the result is UserCanceled. In contrast, if you cancel from code with CancellationToken or CancelCurrentSession(), the result is a Failure whose Code is Cancelled.
Notes for Windows
On Windows, you must put the redirect URI reserved with AllocateLoopbackRedirectUriAsync() in OpenRequest.RedirectUri. If you call it without reserving one, or if you put a value different from the most recently reserved URI, it returns a Failure whose Code is FailedPrecondition.
On Windows, the app user closing the browser is not detected, and there is no time limit, so OpenAsync() does not finish and keeps waiting. Call CancelCurrentSession() from the cancel button on the login screen, or pass a CancellationToken with a time limit.
Exceptions
ArgumentNullException: WhenrequestisnullArgumentException: Whenrequest.Urlorrequest.RedirectUriisnullor empty
Call example
using Hive.Axyl.Auth.Addon.WebAuth;
using Hive.Axyl.Core;
var result = await webAuth.OpenAsync(new OpenRequest
{
Url = authorizationUrl, // Authorization URL built by the app
RedirectUri = redirectUri, // URI at which the app receives the redirect callback
});
switch (result)
{
case ExternalUserAgentServiceOpenResult.Success success:
if (success.Data.Parameters.TryGetValue("error", out var providerError))
{
// An error that the external authentication provider sent in the callback.
}
else if (success.Data.Parameters.TryGetValue("code", out var code))
{
// Verify state, and then use code in the login flow.
}
break;
case ExternalUserAgentServiceOpenResult.UserCanceled:
// The app user closed the authentication screen.
break;
case ExternalUserAgentServiceOpenResult.Failure failure:
HiveError error = failure.Problem;
break;
default:
// Unhandled results and UnknownOutcome
break;
}
Even when Success is returned, the external authentication provider may send an error such as error=access_denied in the callback. Do not assume that an authorization code is present; check the values in Parameters.
Do not log callback data
Data.CallbackUrl and Data.Parameters can contain the authorization code, state, and tokens from the external authentication provider. Do not record them in logs, crash reports, or analytics events.
For the implementation procedure, see Open a web login session.
CancelCurrentSession
Cancels the in-progress session from code. A pending OpenAsync() ends with a Failure whose Code is Cancelled. If no session is in progress, it does nothing.
For the implementation procedure, see Cancel an in-progress session.
WebAuthSessionPlugin
The class that AddWebAuth() registers as IExternalUserAgent. It wraps each platform's authentication-only browser session as IExternalUserAgent and limits it so that only one session proceeds at a time. Only when you need the Windows loopback agent, check that the IExternalUserAgent you retrieved with HiveCore.TryResolve<T>() is this class, and then use it.
WindowsLoopback
The Windows-only loopback agent. Use it to reserve a redirect URI with AllocateLoopbackRedirectUriAsync() before you call OpenAsync(). On platforms other than Windows, it is null.
IWindowsLoopbackAgent
An interface that reserves a temporary loopback port and an HTTP listener on Windows. A loopback address, such as 127.0.0.1, is an address that can be reached only from within the same device. Because Windows has no OS-provided authentication-only browser session, the authorization URL is opened in the default browser, and the redirect callback is received at the reserved loopback address using the loopback interface redirection method in section 7.3 of RFC 8252. You retrieve this interface through WebAuthSessionPlugin.WindowsLoopback.
AllocateLoopbackRedirectUriAsync
Reserves a temporary loopback port, binds an HTTP listener in advance, and then returns a redirect URI in the http://127.0.0.1:<port><path> format. Put the returned URI as is in OpenRequest.RedirectUri. If the external authentication provider allows loopback addresses as redirect URIs, put the same value in the redirect URI of the authorization URL as well. When you log in with an external authentication provider that does not allow loopback addresses, such as Apple, the callback is received at the reserved address through the Hive Axyl relay URL.
If you call it again before you call OpenAsync(), it releases the previous listener and reserves a new port, so the URI you received earlier can no longer be used. The listener is released after it receives the redirect callback once, so a reserved URI can be used for only one OpenAsync() call. When you log in again, reserve a new URI with this method.
- Request: AllocateLoopbackRedirectUriRequest
- Response: AllocateLoopbackRedirectUriResponse
Result cases — WindowsLoopbackServiceAllocateLoopbackRedirectUriResult
| Result case | Wire code | Description |
|---|---|---|
Success | — | The redirect URI has been reserved. Data.RedirectUri contains the reserved URI. |
UnknownOutcome | UNKNOWN | A new result unknown to this SDK version. |
Failure | FAILURE | The call could not be completed. Check the cause with the HiveError in Problem. If no port is available for binding, Code is ResourceExhausted. If local port binding is blocked, it is Unavailable. If the PathPrefix format is invalid, it is InvalidArgument. |
Exceptions
ArgumentNullException: WhenrequestisnullArgumentException: Whenrequest.PathPrefixisnull
Call example
using Hive.Axyl.Auth.Addon.WebAuth;
if (webAuth is not WebAuthSessionPlugin { WindowsLoopback: { } loopback })
{
// Not Windows, so there is no loopback agent.
return;
}
var allocated = await loopback.AllocateLoopbackRedirectUriAsync(new AllocateLoopbackRedirectUriRequest
{
PathPrefix = "/hive-auth/callback",
});
if (allocated is not WindowsLoopbackServiceAllocateLoopbackRedirectUriResult.Success success)
{
return;
}
string redirectUri = success.Data.RedirectUri; // Example: http://127.0.0.1:54321/hive-auth/callback
string authorizationUrl = BuildAuthorizationUrl(redirectUri); // Code in which the app builds the authorization URL
var result = await webAuth.OpenAsync(new OpenRequest
{
Url = authorizationUrl,
RedirectUri = redirectUri, // Put the reserved URI as is.
});
For the implementation procedure, see Prepare the redirect URI.
Data types
AllocateLoopbackRedirectUriRequest
| Field | Type | Required | Description |
|---|---|---|---|
PathPrefix | string | Required | The path of the redirect URI. Example: /hive-auth/callback. If you enter a value, it must start with /. If it is an empty string, the default path /hive-auth/callback is used. If it is null, ArgumentException is thrown. |
AllocateLoopbackRedirectUriResponse
| Field | Type | Required | Description |
|---|---|---|---|
RedirectUri | string | Required | The reserved loopback redirect URI. Example: http://127.0.0.1:54321/hive-auth/callback. Put it as is in OpenRequest.RedirectUri to receive the callback with the reserved listener. |
OpenRequest
| Field | Type | Required | Description |
|---|---|---|---|
Url | string | Required | The OAuth authorization URL to open in the authentication-only browser session. Enter the value the app built. If it is empty, ArgumentException is thrown. |
RedirectUri | string | Required | The URI at which the app receives the redirect callback. On iOS and macOS, the app receives the callback that returns with the scheme of this value. On Windows, it must be the same as the URI reserved with AllocateLoopbackRedirectUriAsync(). On Android, you cannot change the scheme with this value; the app receives the callback with the scheme registered in the manifest at build time. For logins that go through the Hive Axyl relay URL, enter the app callback URL, not the relay URL you put in the authorization URL. If it is empty, ArgumentException is thrown. |
OpenResponse
The result of receiving the redirect callback. The Add-on passes the OAuth values as is without verifying them.
| Field | Type | Required | Description |
|---|---|---|---|
CallbackUrl | string | Required | The original redirect callback URL delivered by the platform. Example: com.myapp://cb?code=abc&state=xyz. It can contain the authorization code, state, and tokens from the external authentication provider. |
Parameters | IReadOnlyDictionary<string, string> | Required | The parsed query parameters of CallbackUrl. The app is responsible for interpreting all values, including code and state as well as errors from the external authentication provider such as error=access_denied. |