The Supabase UE5 Plugin provides comprehensive OAuth authentication support through the UAsyncOAuth class. This production-ready implementation offers multiple authentication flows, enhanced security features, and seamless integration with the Supabase ecosystem.
EOAuthFlowType::PKCE
The most secure flow, designed for public clients. Uses dynamic code challenge/verifier pairs to prevent authorization code interception attacks.
EOAuthFlowType::AuthorizationCode
Traditional OAuth flow suitable for server-side applications with client secrets.
EOAuthFlowType::Implicit
Direct token return flow, suitable for SPAs but less secure than PKCE.
| Provider | Authentication URL | Token URL |
|---|---|---|
https://accounts.google.com/oauth2/v2/auth |
https://oauth2.googleapis.com/token |
|
| GitHub | https://github.com/login/oauth/authorize |
https://github.com/login/oauth/access_token |
https://www.facebook.com/v18.0/dialog/oauth |
https://graph.facebook.com/v18.0/oauth/access_token |
|
| Supabase | {SupabaseServerUrl}/auth/v1/authorize |
{SupabaseServerUrl}/auth/v1/token |
// Create authentication provider
UAuthenticationProvider* AuthProvider = NewObject<UAuthenticationProvider>();
AuthProvider->Provider = EAuthProvider::Google;
AuthProvider->ClientID = TEXT("your-client-id");
AuthProvider->ClientSecret = TEXT("your-client-secret");
AuthProvider->RedirectURI = TEXT("https://yourapp.com/callback");
// Start OAuth flow with PKCE (recommended)
UAsyncOAuth* OAuthTask = UAsyncOAuth::OAuthAsync(this, AuthProvider, EOAuthFlowType::PKCE);
OAuthTask->OnSuccess.AddDynamic(this, &AMyClass::OnOAuthSuccess);
OAuthTask->OnFailure.AddDynamic(this, &AMyClass::OnOAuthFailure);
OAuthTask->Activate();
// Get authorization URL for browser
FString AuthURL = OAuthTask->GetAuthorizationURL();
// Open AuthURL in browser or webview
// Handle the callback and extract authorization code
OAuthTask->HandleAuthorizationResponse(AuthorizationCode, State);
TArray<FString> Scopes;
Scopes.Add(TEXT("email"));
Scopes.Add(TEXT("profile"));
UAsyncOAuth* OAuthTask = UAsyncOAuth::OAuthWithScopesAsync(
this,
AuthProvider,
Scopes,
EOAuthFlowType::PKCE
);
FString CustomState = TEXT("custom-state-value");
TArray<FString> Scopes = {TEXT("email"), TEXT("profile")};
UAsyncOAuth* OAuthTask = UAsyncOAuth::OAuthSecureAsync(
this,
AuthProvider,
CustomState,
Scopes,
EOAuthFlowType::PKCE
);
USupabaseConnection* Connection = GetMyConnection();
UAsyncOAuth* OAuthTask = UAsyncOAuth::OAuthAdvanced(
this,
Connection,
AuthProvider,
EOAuthFlowType::PKCE
);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOAuthSuccessDelegate,
const FString&, AccessToken,
const FString&, RefreshToken
);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOAuthFailureDelegate,
const FString&, ErrorMessage
);
UFUNCTION()
void OnOAuthSuccess(const FString& AccessToken, const FString& RefreshToken)
{
// Store tokens securely
CurrentAccessToken = AccessToken;
CurrentRefreshToken = RefreshToken;
// Update UI or proceed with authenticated requests
UpdateUIForAuthenticatedState();
}
UFUNCTION()
void OnOAuthFailure(const FString& ErrorMessage)
{
UE_LOG(LogTemp, Error, TEXT("OAuth failed: %s"), *ErrorMessage);
// Handle authentication failure
ShowErrorMessage(ErrorMessage);
}
| Error | Description | Solution |
|---|---|---|
| “OAuth Client ID is required” | Missing client ID in provider | Set AuthProvider->ClientID |
| “OAuth Redirect URI is required” | Missing redirect URI | Set AuthProvider->RedirectURI |
| “Invalid redirect URI format” | Malformed redirect URI | Use http/https/custom scheme format |
| “State parameter mismatch” | CSRF attack detected | Check state parameter handling |
| “Authorization code is empty” | Missing auth code in callback | Verify callback URL parsing |
// OAuth automatically uses the active Supabase connection
UAsyncOAuth* OAuthTask = UAsyncOAuth::OAuthAsync(this, AuthProvider);
// Subsystem connection is used automatically
// Use specific connection instance
USupabaseConnection* MyConnection = CreateMyConnection();
UAsyncOAuth* OAuthTask = UAsyncOAuth::OAuthAdvanced(this, MyConnection, AuthProvider);
OAuth not starting
State parameter mismatch
Token exchange failure
Browser/WebView integration
// Primary OAuth method using subsystem
static UAsyncOAuth* OAuthAsync(
UObject* WorldContextObject,
UAuthenticationProvider* AuthProvider,
EOAuthFlowType FlowType = EOAuthFlowType::PKCE
);
// Advanced OAuth with direct connection
static UAsyncOAuth* OAuthAdvanced(
UObject* WorldContextObject,
USupabaseConnection* Connection,
UAuthenticationProvider* AuthProvider,
EOAuthFlowType FlowType = EOAuthFlowType::PKCE
);
// OAuth with custom scopes
static UAsyncOAuth* OAuthWithScopesAsync(
UObject* WorldContextObject,
UAuthenticationProvider* AuthProvider,
const TArray<FString>& Scopes,
EOAuthFlowType FlowType = EOAuthFlowType::PKCE
);
// OAuth with state parameter for security
static UAsyncOAuth* OAuthSecureAsync(
UObject* WorldContextObject,
UAuthenticationProvider* AuthProvider,
const FString& State,
const TArray<FString>& Scopes,
EOAuthFlowType FlowType = EOAuthFlowType::PKCE
);
// Handle authorization callback
void HandleAuthorizationResponse(const FString& AuthorizationCode, const FString& State = TEXT(""));
// Cancel ongoing OAuth operation
void CancelOAuth();
// Get authorization URL for manual browser opening
FString GetAuthorizationURL() const;
// Check if OAuth is currently in progress
bool IsOAuthInProgress() const;
This documentation is part of the Supabase UE5 Plugin v1.34.2 by Seven Mountains Labs.