Step 2. Log in
Implement login so that users can log in to your app with their X (Twitter) account without a separate sign-up. Before you begin, complete Step 1. Set up the integration.
X does not provide a dedicated Add-on, so on all OSs you open the X login page with a web login session. The web login session returns only the X authorization code. Login follows the Authorization Code flow, in which you exchange the authorization code through Exchange external authorization codes and then log in.
X requires PKCE. Generate a pair of PKCE values before you build the authorization URL, and keep codeVerifier in the app until the external authorization code exchange step.
1. Get X credentials
Open the X login page with a web login session and receive the authorization code. The authorization URL composition and the response parameters follow the OAuth 2.0 specification that X defines, so check the required parameters in the X developer documentation.
Build the authorization URL
Login works correctly only when you put the following values in the authorization URL.
- Client ID checked in the X Developer Portal
- Redirect URI registered in the allowlist of the X Developer Portal
- PKCE
code_challenge state, a random value created anew for every login attempt
state is a value that filters out authentication results that the app did not start, so store the value you created and compare it in Check the callback.
Check the callback
A web login session only returns the callback parameters as is and does not verify them, so when you receive the callback, check state first. If the callback's state differs from the stored value, the response was not started by this login, so stop the login. Even if state matches, stop the login if error is present or code is missing. If error is access_denied, the user declined login; any other error means login failed.
using Hive.Axyl.Auth.Addon.WebAuth;
using Hive.Axyl.Core;
if (!HiveCore.TryResolve<IExternalUserAgent>(out var webAuth))
{
return;
}
// Generate and store the PKCE values for X before you build the authorization URL.
var (xVerifier, xChallenge) = CreatePkce();
// Create a new value for every login attempt and store it.
string state = CreateNonce();
// The app builds the authorization URL according to the X OAuth 2.0 specification.
string authorizationUrl = BuildXAuthorizationUrl(xChallenge, state, redirectUri);
var sessionResult = await webAuth.OpenAsync(new OpenRequest {
Url = authorizationUrl,
RedirectUri = redirectUri,
});
if (sessionResult is not ExternalUserAgentServiceOpenResult.Success session)
{
// For handling UserCanceled and Failure, see [Web login session](web-auth-session.md)
return;
}
var callback = session.Data.Parameters;
// Check state first.
if (!callback.TryGetValue("state", out var returnedState) || returnedState != state)
{
// Not a response started by this login → stop the login
return;
}
if (callback.TryGetValue("error", out var xError))
{
// If "access_denied", the user declined → keep the login screen
// For any other value, login failed → stop the login
return;
}
if (!callback.TryGetValue("code", out var xCode))
{
// No authorization code → stop the login
return;
}
CreatePkce() is a helper defined in Create a guest account, and CreateNonce() is a random value generation helper defined in Sign in with Apple. BuildXAuthorizationUrl() is authorization URL generation code that the app implements itself.
2. Exchange external authorization codes
Send the received authorization code to Exchange external authorization codes to turn it into credentials to use for login. Put the following values in the exchange request.
ProviderId:Provider.XProviderCode:codefrom the callbackRedirectUri: A value identical, character for character, to the value you put inredirect_uriof the authorization URLCodeVerifier: ThecodeVerifierthat you generated and stored before building the authorization URL. Required for X
using Hive.Axyl.Auth;
using Hive.Axyl.Core;
IAuthService auth = HiveCore.Resolve<IAuthService>();
var exchange = await auth.ExchangeProviderTokenAsync(new ProviderTokenRequest {
ProviderId = Provider.X,
ProviderCode = xCode,
RedirectUri = redirectUri, // Same value as redirect_uri of the authorization URL
CodeVerifier = xVerifier, // X requires PKCE.
});
if (exchange is not AuthExchangeProviderTokenResult.Success exchanged)
{
// For handling exchange failures, see [Exchange external authorization codes](provider-token-exchange.md)
return;
}
string xProviderToken = exchanged.Data.ProviderToken; // ProviderToken of the login request
string xProviderUserId = exchanged.Data.ProviderUserId; // ProviderUserId of the login request
3. Log in with an external authentication provider
Call Log in with an external authentication provider with the xProviderUserId and xProviderToken you got from the exchange. Specify Provider.X for ProviderId.
using Hive.Axyl.Auth;
using Hive.Axyl.Core;
IAuthService auth = HiveCore.Resolve<IAuthService>();
// Create new PKCE values for the Axyl authentication server, separate from the PKCE values for X.
var (codeVerifier, codeChallenge) = CreatePkce();
var result = await auth.LoginProviderAsync(new ProviderLoginRequest {
ProviderId = Provider.X,
ProviderUserId = xProviderUserId,
ProviderToken = xProviderToken,
DeviceKey = deviceKey,
ClientId = "{clientId}",
CodeChallenge = codeChallenge,
CodeChallengeMethod = CodeChallengeMethod.S256,
});
if (result is AuthLoginProviderResult.Success success)
{
// Login succeeded → issue tokens and activate the session.
await StartSessionAsync(success.Data.AuthorizationCode, codeVerifier, success.Data.PlayerId);
}
// For other response cases and the full call parameters, see [Log in with an external authentication provider](provider-login.md)
For the definition of StartSessionAsync() and the session activation procedure, see Issue tokens and activate the session.