Implement X login
To implement X login with the recipe code, complete the following procedure in order.
Before you begin, complete the common prerequisites.
Overall flow
What you configure and call in each step is as follows.
| Step | Category | What you do |
|---|---|---|
| 1 | External console | Prepare the X OAuth app, Callback URI, and Scope |
| 2 | Hive Console | Enable X login and register credentials |
| 3 | Hive Axyl SDK | Install the authentication module and the WebAuth Add-on |
| 4 | Hive Axyl SDK | Initialize the SDK and register modules |
| 5 | Recipe code | Copy the common and WebAuth recipe folders |
| 6 | App code, Recipe code | Prepare the Hive Axyl ClientId, DeviceKey, and OAuth settings |
| 7 | Recipe code | Prepare the X credential source |
| 8 | Recipe code | Call X login |
| 9 | App code | Handle login results |
| 10 | App code | Verify the behavior |
Distinguish the Hive Axyl Client ID from the X Client ID
Put the ClientId you check in the Hive Console in the ProviderLoginRecipe constructor, and put the OAuth Client ID issued by the X Developer Portal in WebAuthOptions.ClientId. If you swap the two values, X authentication or Hive Axyl login fails.
1. Configure the X external console
-
External console Configure this in the X Developer Portal.
Detailed procedure: X login integration
Prepare the Client ID, Callback URI, and Scope of the OAuth app in the X Developer Portal.
The values that the recipe uses when it builds the X authorization URL and exchanges credentials, and where you put them, are as follows.
- OAuth Client ID:
WebAuthOptions.ClientId - Callback URI:
WebAuthOptions.RedirectUriand the allowlist in the X Developer Portal - Scope:
WebAuthOptions.Scope - Authorization endpoint:
WebAuthOptions.AuthorizeEndpoint - Token endpoint:
WebAuthOptions.TokenEndpointin the public client method - User information endpoint:
WebAuthOptions.UserInfoEndpointin the public client method
The following are example values based on OAuth 2.0 Authorization Code Flow with PKCE and GET /2/users/me in the X developer documentation.
- Authorization endpoint:
https://x.com/i/oauth2/authorize - Scope:
tweet.read users.read - Token endpoint:
https://api.x.com/2/oauth2/token - User information endpoint:
https://api.x.com/2/users/me
Check the Scope and endpoints in the X developer documentation according to your app's X OAuth settings and the scope of user information to request. The Callback URI registered in the X Developer Portal and the value you put in the app settings must be exactly the same.
Do not put the X Client Secret in a public client app. When you use the server exchange method, register the Secret only in the Hive Console.
2. Configure the Hive Console
-
Hive Console Configure or check this in the Hive Console.
Detailed procedure: X(Twitter) login credentials, Login method types
Register the X login credentials and enable the login method. If the settings are empty or the login method is disabled, the recipe's Hive Axyl login step is rejected.
Configure the following items.
| Setting | Required | Where to check |
|---|---|---|
| Register the X Client ID | Required | X(Twitter) login credentials |
| Register the X Client Secret | Required when you use the server exchange method | X(Twitter) login credentials |
| Enable X(Twitter) login | Required | Login method types |
| Per-App ID login settings | Optional | Per-App ID login settings |
In the public client method, the recipe exchanges directly with X's token endpoint, so the Client Secret is not passed to the app. In the Hive Console, register the project's X login credentials to enable the login method, and keep the Secret to use when you choose the server exchange method.
3. Install SDK modules and Add-ons
-
Hive Axyl SDK Call the Hive Axyl SDK from the app.
Detailed procedure: Install modules, Install the X login Add-on
Install the Hive Axyl SDK modules and the WebAuth Add-on required for X login in your Unity project.
| Package | Needed | Role |
|---|---|---|
com.com2usplatform.hiveaxyl.core | Required | SDK initialization and common error handling |
com.com2usplatform.hiveaxyl.auth | Required | Login with X credentials and token issuance |
com.com2usplatform.hiveaxyl.storage | Recommended | Encrypted storage of the DeviceKey and session tokens |
com.com2usplatform.hiveaxyl.auth.addon.webauth | Required | Providing the browser web login session |
com.unity.nuget.newtonsoft-json | Required | JSON processing in ProviderLogin.WebAuth/ |
If you do not install the WebAuth Add-on package, the ProviderLogin.WebAuth/ recipe assembly is excluded from compilation, so app code that uses XCredentialSource does not compile. Even if you installed the package, the X credential source returns Unavailable if you did not register AddWebAuth() or if you run the app in the Unity Editor. After installing the package, also register AddWebAuth() as described in Initialize modules.
4. Initialize the SDK
-
Hive Axyl SDK Call the Hive Axyl SDK from the app.
Detailed procedure: Initialize modules
Register the authentication, token, secure storage, and WebAuth modules once at the app's entry point. The recipe does not initialize the SDK.
using Hive.Axyl.Auth;
using Hive.Axyl.Auth.Addon.WebAuth;
using Hive.Axyl.Core;
using Hive.Axyl.Core.Unity;
using Hive.Axyl.Storage;
var config = CoreConfig.CreateBuilder("{appId}").Build();
HiveBootstrap.Initialize(config, builder =>
{
builder
.AddAuth()
.AddToken()
.AddSecureStorage()
.AddWebAuth();
});
For {appId}, enter the App ID you created in the Hive Console. AddWebAuth() registers the actual module only on supported OSs and does not register it in the Unity Editor.
5. Install the recipe code
- Recipe code Copy the recipe code into your project.
A recipe is source code that you copy into your project instead of installing as a package. Copy the following items from the axyl-samples-unity repository to Assets/Recipes/ in your Unity project.
The items to copy and their roles are as follows.
- Recipes.asmdef: Common assembly definition for recipes
- AssemblyInfo.cs: Setting that exposes internal helpers to other recipe assemblies
- Helper/: Common code shared by multiple recipes
- ProviderLogin/:
ProviderLoginRecipe, result types, and the credential source contract - ProviderLogin.WebAuth/:
XCredentialSourceand common browser login code
To call recipes from your app code, add the following assemblies to references in your app's assembly definition.
Replace MyApp with the assembly name your app uses, and keep your existing settings and references. Unity assemblies do not pass references on transitively, so you must list every assembly that your app code uses directly. When you use ProviderLogin.WebAuth/, you must also install the com.unity.nuget.newtonsoft-json package.
Copy the common recipe folder as well
ProviderLogin.WebAuth/ implements the credential source contract in ProviderLogin/, and ProviderLoginRecipe uses the common code in Helper/. Copy Helper/, Recipes.asmdef, AssemblyInfo.cs, and ProviderLogin/ together.
6. Prepare ClientId, DeviceKey, and OAuth settings
-
App code Implement this in the app.
Recipe code Call the recipe code from the app.
Detailed procedure: Client ID, deviceKey, Prepare the redirect URI
The constructor of ProviderLoginRecipe takes ClientId and DeviceKey. ClientId is the value you checked in the common prerequisites, which the Hive Console issues for each project. DeviceKey is the value the Hive Axyl authentication server uses to distinguish login sessions by device, and the app creates and keeps it itself. Pass WebAuthOptions, which contains the X OAuth settings, to XCredentialSource.
| Value | Where to put it | How to prepare |
|---|---|---|
Hive Axyl ClientId | new ProviderLoginRecipe(clientId, deviceKey) | Check it in the security key in the Hive Console |
DeviceKey | new ProviderLoginRecipe(clientId, deviceKey) | Created and kept by the app |
| X OAuth Client ID | clientId of WebAuthOptions.Create() | Check it in the X Developer Portal |
| Authorization endpoint | authorizeEndpoint of WebAuthOptions.Create() | Check it in the X OAuth settings |
| Callback URI | redirectUri of WebAuthOptions.Create() | Set it to the same value you registered in the X Developer Portal |
| Scope | scope of WebAuthOptions.Create() | Set it to match the scope allowed in the X Developer Portal |
The recipe does not create or save DeviceKey, so create and manage it according to the following conditions.
- A different value for each device. A random value such as a UUID is recommended
- A value created and saved once on first launch and reused for every later login
- A length of 22 to 64 characters
- A value made up only of ASCII characters, excluding spaces and control characters
Do not overwrite it with a new DeviceKey just because the storage could not be read
The value may not be gone; only the read may have failed. First fix the storage access problem or try reading again.
If ClientId or DeviceKey is empty, the recipe constructor throws an ArgumentException. An exception is also thrown at creation if a required value of WebAuthOptions is empty, so validate the settings after you read them.
X requires PKCE. The recipe creates PKCE for X for each login attempt and validates the state of the callback, so do not create PKCE and state again in the app.
6.1. Select the redirect URI
The method that creates WebAuthOptions differs depending on the redirect URI that receives the callback. Use WebAuthOptions.Create() to specify a fixed Callback URI registered in the X Developer Portal, and use WebAuthOptions.WithLoopbackRedirect() to specify a local address whose port changes every time the app runs on Windows.
6.1.1. Fixed Callback URI
The following example code creates X OAuth settings with a fixed Callback URI.
{xRedirectUri} must be the same as the Callback URI in the X Developer Portal. On Android, set the URL scheme in launcherTemplate.gradle as described in Prepare the redirect URI. iOS and macOS need no additional settings and use a Callback URI with a scheme.
6.1.2. Windows local address
On Windows, the WebAuth Add-on receives the callback at a local address whose port changes every time the app runs. If X allows redirects to local addresses with variable ports, specify a path such as /hive-auth/callback in WebAuthOptions.WithLoopbackRedirect() instead of WebAuthOptions.Create(). The recipe reserves a local address each time the user logs in and puts it in the authorization request. For the addresses to register in the X Developer Portal, see Addresses to register in the allowlist. Settings created with WithLoopbackRedirect() work only on Windows, where a local address can be reserved.
6.2. Token exchange for public clients
If the X OAuth client is a public client that is not issued a Client Secret, specify tokenEndpoint and userInfoEndpoint. The recipe receives access_token from the X token endpoint and reads data.id from the user information endpoint.
If you leave tokenEndpoint empty, the recipe uses ExchangeProviderTokenAsync() of the Hive Axyl SDK. In this case, the Hive Axyl authentication server performs the exchange with X using the X Client Secret in the Hive Console. Choose only one of the two paths, and do not put the Client Secret in the app code.
7. Prepare the X credential source
-
Recipe code Call the recipe code from the app.
Detailed procedure: Get X credentials
Create XCredentialSource with the prepared WebAuthOptions, and then pass it to the recipe.
XCredentialSource builds the X authorization URL and calls the WebAuth Add-on. The app must not call OpenAsync() directly or create PKCE for X again. For the session and cancellation handling of the WebAuth Add-on, see Web login session.
8. Call X login
- Recipe code Call the recipe code from the app.
Pass the prepared credential source to LoginWithProviderAsync(). The recipe continues through X credential acquisition, Hive Axyl login, token issuance, and session activation.
Call cancellation.Cancel() when the app needs to stop waiting, such as when it closes the login screen, and clean up with cancellation.Dispose() when the call finishes. On Android, iOS, and macOS, when the user closes the X screen, do not call the cancellation token; handle the UserCanceled that the recipe returns instead.
On Windows, an external browser is used, so even if the user closes the browser, the recipe does not detect it and keeps waiting. Put a cancel button on the login screen that calls cancellation.Cancel(), or specify a time limit, as in new CancellationTokenSource(TimeSpan.FromMinutes(5)). To use TimeSpan, add using System;. For details, see the response status in Open a web login session.
The recipe performs the following tasks internally.
| Category | Call | Where to check |
|---|---|---|
| Recipe code | Checks that the authentication, token, and session modules are registered | Initialize modules |
| Add-on | On Windows, reserves the local address that receives the callback with AllocateLoopbackRedirectUriAsync() | Prepare the redirect URI |
| Recipe code | Creates the X authorization URL, state, and PKCE for X | Build the authorization URL |
| Add-on | Opens the X login page with OpenAsync() and receives the callback | Open a web login session |
| Recipe code | Validates the state of the callback | Check the callback |
| Hive Axyl SDK | If tokenEndpoint is left empty, exchanges the X authorization code with ExchangeProviderTokenAsync(). Puts the redirect URI used in the authorization request in RedirectUri and the PKCE value for X, which X requires, in CodeVerifier | Exchange external authorization codes |
| Recipe code | If tokenEndpoint is specified, directly calls the X token endpoint and the user information endpoint | Token exchange for public clients |
| Hive Axyl SDK | Passes the prepared X credentials to LoginProviderAsync() | Log in with an external authentication provider |
| Hive Axyl SDK | Issues Hive Axyl tokens with IssueTokenAsync() and activates the session with SetSession() | Issue tokens and activate the session |
The recipe calls the SDK methods in the table above internally. Apps that use the recipe must not call ExchangeProviderTokenAsync(), LoginProviderAsync(), IssueTokenAsync(), or SetSession() again. The PKCE for X and the PKCE for Hive Axyl are different values, and the recipe manages both.
In the public client method with tokenEndpoint specified, the recipe sends the HTTP requests directly to X. These requests are not Hive Axyl Server API calls, and they do not include the Client Secret.
9. Handle login results
-
App code Implement this in the app.
Detailed procedure: HiveError information
Check Status of LoginWithProviderOutcome first, and then read the other values according to the status. FailedStep is a diagnostic value, so do not use it as the basis for branching the normal flow.
Status | Value to check | App handling |
|---|---|---|
Success | PlayerId, IsBlocked | If the account is not under a usage restriction, move to the post-login screen. |
BusinessOutcome | BusinessOutcome, UnknownOutcomeCode | Branch according to the rejection reason, and handle and record unknown values as failures. |
UserCanceled | None | The user closed the X login screen or declined consent, so keep the login screen. |
Failure | Error.Code, Error.TraceId | Record the technical problem, and provide a retry or another login method. |
The PlayerId in Success is the same value when the user logs in again with the same X account. If IsBlocked is true, login succeeded but the account is under a usage restriction, so notify the user based on Usage restriction.
Distinguish UserCanceled from Cancelled in Failure. If the user closes the X authentication screen or declines consent, the result is UserCanceled. If the app stops waiting with a CancellationToken, the result is Failure with HiveErrorCode.Cancelled. On Windows, UserCanceled is not returned even if the user closes the browser, so the app must end the wait with its own cancellation handling.
| Situation | Recipe result | App handling |
|---|---|---|
| The user declines consent on the X authentication screen | UserCanceled | Keep the login screen |
| The user closes the X authentication screen on an OS other than Windows | UserCanceled | Keep the login screen |
| The WebAuth Add-on is not registered | Failure and Unavailable | Check the installation in step 3 and the AddWebAuth() registration in step 4 |
The state of the callback differs from the current login request | Failure and PermissionDenied | The callback did not start from this login, so keep the login screen and let the user try again |
| The public client's token or user information request fails | Failure | Check the X endpoints, Scope, Client ID, and network status |
| The Hive Axyl server rejects the X credentials | BusinessOutcome or Failure | Check the X console and Hive Console settings and whether the authentication has expired |
| The app cancels the wait | Failure and Cancelled | Clean up the in-progress login screen and keep the login screen |
BusinessOutcome can include values such as ProviderConfigNotFound, ProviderClientInfoNotExists, ProviderTokenError, InvalidAuthorizationCode, ExpiredAuthorizationCode, CodeChallengeMismatch, and TemporarilyUnavailable. The recipe combines the rejection reasons from multiple calls into a single value and returns it, so check External authentication provider login response status and Issue an access token and a refresh token. If you use the server exchange, also check External authorization code exchange response status. Retry only TemporarilyUnavailable, at increasing intervals such as 1 second, 3 seconds, and 6 seconds. For the rest, check the settings or the authentication status first.
Do not leave X authorization codes, access tokens, or WebAuth callback URLs in logs, crash reports, or analytics events. Do not show UnknownOutcomeCode and RawJson to users; use them only when you need to record app errors.
10. Verify the behavior
- App code Verify the behavior in the app.
WebAuth does not provide the actual authentication screen in the Unity Editor, so verify the behavior on supported devices and builds.
- Save the X Developer Portal and Hive Console settings, and then build the app for the target OS.
- Check that the X login screen opens and that the user returns to the app through the Callback URI.
- On Windows, check that the callback returns to the local address that the recipe reserved with the
WithLoopbackRedirect()settings. - Check
SuccessandPlayerId, and check that the app moves to the post-login screen. - Quit the app completely, log in again with the same X account, and check that
PlayerIdis the same. - On Android, iOS, and macOS, close the authentication screen and check that
UserCanceledis returned. On Windows, decline consent to check forUserCanceled, and check thatFailureandCancelledare returned when you use the cancel button or the time limit.
Next steps
To let logged-in users skip the login screen when they relaunch the app, see Automatic login.
To link another login method to an account that is already logged in, see External authentication provider linking.
To leave the logged-in account and log in with a different account, see Logout.