The Supabase Unreal Engine plugin implements a comprehensive token management system for handling authentication tokens, including JWT access tokens and refresh tokens. This system ensures secure authentication, automatic token refresh, and persistent session management.
SupabaseCredentials.UserAuthenticatedKeyJWTRefreshToken (client) and SupabaseCredentials.RefreshToken (connection)SupabaseCredentials.AnonymousKeyUSTRUCT(BlueprintType)
struct FTokenResponse
{
GENERATED_BODY()
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Supabase Authentication")
FString AccessToken;
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Supabase Authentication")
FString TokenType;
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Supabase Authentication")
int32 ExpiresIn = 0;
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Supabase Authentication")
int64 ExpiresAt = 0;
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Supabase Authentication")
FString RefreshToken;
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Supabase Authentication")
FUser User;
};
{SupabaseURL}/auth/v1/tokenhttps://oauth2.googleapis.com/tokenhttps://github.com/login/oauth/access_tokenhttps://graph.facebook.com/v18.0/oauth/access_tokenThe system implements automatic token refresh to maintain authentication without user intervention:
void USupabaseClient::RefreshToken()
{
TSharedRef<IHttpRequest> RefreshRequest = FHttpModule::Get().CreateRequest();
RefreshRequest->SetURL(FString::Printf(TEXT("%s/auth/v1/token?grant_type=refresh_token"),
*SupabaseConnection->SupabaseServerUrl));
RefreshRequest->SetVerb(TEXT("POST"));
FString JsonPayload = FString::Printf(TEXT("{\"refresh_token\":\"%s\"}"), *JWTRefreshToken);
RefreshRequest->SetContentAsString(JsonPayload);
}
RefreshToken() method callsTokens are persisted using the USupabaseSessionSave system:
struct SaveGame {
USupabaseConnection* SupabaseConnection;
FString Email;
FString Password;
FString RefreshToken;
FDateTime LastLogin;
bool bIsLoggedIn;
FUser User;
}
USupabaseClient and USupabaseConnection objectsLoadSupabaseSession(): Restore tokens from save gameSaveSupabaseSession(): Persist current sessionClearSupabaseSession(): Remove stored credentialsvoid USupabaseClient::IsLoggedIn()
{
TSharedRef<IHttpRequest> HttpRequest = FHttpModule::Get().CreateRequest();
HttpRequest->SetURL(FString::Printf(TEXT("%s/auth/v1/user"), *SupabaseConnection->SupabaseServerUrl));
HttpRequest->SetVerb(TEXT("GET"));
CreateHeader(HttpRequest, SupabaseConnection->SupabaseCredentials.UserAuthenticatedKey);
}
void CreateHeader(TSharedRef<IHttpRequest> Request, const FString& Token)
{
Request->SetHeader(TEXT("Authorization"), FString::Printf(TEXT("Bearer %s"), *Token));
Request->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
Request->SetHeader(TEXT("apikey"), *SupabaseConnection->SupabaseCredentials.AnonymousKey);
}
UserAuthenticatedKey (access token)AnonymousKey (public API key)Enable debug logging to monitor token operations:
SupabaseSubsystem->EnableDebugLogging(true);
RefreshToken(): Manual token refreshIsLoggedIn(): Validate current authenticationSetSupabaseCredentials(): Update stored credentialsLoadSupabaseSession(): Restore from persistenceSaveSupabaseSession(): Save to persistenceSupabaseLoginSuccessful: Token acquisition successSupabaseRequestFailed: Token operation failureOnSupabaseLoggedIn: Authentication status change// Check authentication status
SupabaseSubsystem->IsAuthenticated();
// Manual token refresh
SupabaseSubsystem->RefreshToken();
// Clear session
SupabaseSubsystem->Logout();
// Load saved session
FSupabaseCredentials Credentials;
FUser User;
if (USupabaseUtils::LoadSupabaseSession(Credentials, User))
{
// Session restored successfully
}
// Save current session
USupabaseUtils::SaveSupabaseSession(Credentials, User);