← All extensions

Native extension

KlugAuth

com.klug.auth.KlugAuth

NO APM NEEDED. Download and enjoy. It can’t get any simpler. Just update the Adobe AIR SDK. If you need help, we are here.

Sign in with Apple and Sign in with Google from ActionScript, with the system sign-in sheets. Your app receives a verified identity token for your server, so users create an account without inventing a password.

iOSAndroidmacOSiPad on Mac In production From €9 / year · Buy

Overview

Most users give up at the registration form: a username, a password they have to remember, an e-mail code that lands in spam. With KlugAuth they tap Continue with Apple or Continue with Google and are done.

KlugAuth shows the native sign-in of each platform: Apple's sheet with Face ID / Touch ID on iOS and macOS, the Android account sheet (Credential Manager) for Google, and the system sign-in window for Google on iOS and macOS. It returns the provider's identity token together with your nonce, ready for verification on your server, plus the Apple authorization code you need to revoke the link when an account is deleted (App Store guideline 5.1.1(v)).

No Google SDK is bundled: Google sign-in on iOS and macOS uses the standard OAuth flow with PKCE in the system browser sheet, so the extension stays small.

KlugAuth runs in the current release of our apps, our proof of concept, for registration, sign-in and confirming a device logout with Apple or Google.

Features

  • Self-contained: one ANE, no core library or dependency ANEs to add
  • Sign in with Apple on iOS 13+, macOS 10.15+ and iPad apps on Apple silicon Macs
  • Sign in with Google on Android (Credential Manager) and on iOS / macOS (system sign-in window, no Google SDK)
  • Identity token, user ID, e-mail and name; Apple authorization code for refresh and revocation
  • Nonce helper for replay protection (Apple carries its SHA-256, Google the raw value)
  • Apple credential state check (authorized / revoked) for returning users
  • Separate success, cancel and error events; cancel is reported, never an error

Supported platforms

iOS Apple + Google · arm64
Android Google · Credential Manager
macOS Apple + Google · arm64 · x86_64
iPad on Mac Apple + Google

Sign in with Apple on Android is possible with Apple's web flow and a small server page; we can provide that as part of a project. isSupported (Apple) and isGoogleSupported tell your code what the device offers.

Getting started

Add the extension to your application descriptor:

app.xml
<extensions>
    <extensionID>com.klug.auth.KlugAuth</extensionID>
</extensions>

For Sign in with Apple, add the entitlement (iOS: Entitlements in the descriptor; macOS: when signing):

app.xml · Entitlements
<key>com.apple.developer.applesignin</key>
<array><string>Default</string></array>

For Google, create OAuth clients in the Google Cloud console: a web client (its ID is the token audience on Android), an Android client with your package name and SHA-1, and an iOS client for iOS and macOS.

Code examples

Five complete flows, from the buttons to your server. Every call returns at once; results arrive as KlugAuthEvents. Full documentation →

1 · Offer what the device supports
SignIn.as
import com.klug.auth.KlugAuth;
import com.klug.auth.KlugAuthEvent;

var auth:KlugAuth = KlugAuth.getInstance();
var nonce:String = "";   // a fresh one for every attempt

appleButton.visible  = auth.isSupported;         // iOS 13+, macOS 10.15+, iPad apps on the Mac
googleButton.visible = auth.isGoogleSupported;   // Android, iOS 13+, macOS 10.15+

auth.addEventListener( KlugAuthEvent.APPLE_SUCCESS,   onAppleSuccess );
auth.addEventListener( KlugAuthEvent.APPLE_CANCELED,  onCanceled );
auth.addEventListener( KlugAuthEvent.APPLE_ERROR,     onError );
auth.addEventListener( KlugAuthEvent.GOOGLE_SUCCESS,  onGoogleSuccess );
auth.addEventListener( KlugAuthEvent.GOOGLE_CANCELED, onCanceled );
auth.addEventListener( KlugAuthEvent.GOOGLE_ERROR,    onError );
2 · Sign in with Apple
Apple.as
function signInWithApple():void
{
    nonce = KlugAuth.generateNonce();          // 32 random bytes as hex, used once
    if ( !auth.signInWithApple( nonce ) )      // false: not supported, or a sheet is already open
        showMessage( "Sign in with Apple is not available." );   // your app function
}

function onAppleSuccess( e:KlugAuthEvent ):void
{
    // the token carries SHA-256 of the nonce: the server hashes the raw value and compares
    sendToServer( "apple", e.identityToken, nonce, e.fullName, e.authorizationCode );
    saveAppleUserID( e.userID );   // stable for this Apple ID; your app function
    // e.email and the names arrive only on the FIRST authorization;
    // the e-mail is always inside the identity token
}

// your app function: the server verifies the token and signs the user in
function sendToServer( provider:String, idToken:String, rawNonce:String,
                       name:String, appleCode:String = "" ):void
{
    var vars:URLVariables = new URLVariables();
    vars.provider = provider;
    vars.id_token = idToken;
    vars.nonce    = rawNonce;
    vars.name     = name;
    if ( appleCode != "" ) vars.code = appleCode;   // lets the server revoke the link later

    var req:URLRequest = new URLRequest( "https://your.server/auth" );
    req.method = URLRequestMethod.POST;
    req.data = vars;
    var loader:URLLoader = new URLLoader();
    loader.addEventListener( Event.COMPLETE, onServerAnswer );   // your app function
    loader.load( req );
}
3 · Sign in with Google
Google.as
import flash.system.Capabilities;

// Android: the WEB client ID, which is the token audience on your server.
// iOS and macOS: the iOS client ID, used in the system sign-in window.
var googleClientId:String = Capabilities.manufacturer.indexOf( "Android" ) >= 0
    ? "YOUR_WEB_CLIENT_ID.apps.googleusercontent.com"
    : "YOUR_IOS_CLIENT_ID.apps.googleusercontent.com";

function signInWithGoogle():void
{
    nonce = KlugAuth.generateNonce();         // Google puts the raw value into the token
    if ( !auth.signInWithGoogle( googleClientId, nonce ) )   // false: no client ID, or already open
        showMessage( "Google sign-in could not start." );
}

function onGoogleSuccess( e:KlugAuthEvent ):void
{
    // e.userID is the account e-mail; names arrive every time
    sendToServer( "google", e.identityToken, nonce, e.fullName );
}
4 · Cancel and errors
Errors.as
function onCanceled( e:KlugAuthEvent ):void
{
    // the user closed the sheet: not an error, simply stay on the start screen
}

function onError( e:KlugAuthEvent ):void
{
    if ( e.type == KlugAuthEvent.GOOGLE_ERROR && e.errorCode == "NO_ACCOUNT" )
        showMessage( "Please add a Google account to this device first." );   // Android
    else
        showMessage( "Sign-in failed: " + e.errorMessage );   // e.errorCode for your log
}
5 · Check a returning Apple user
Startup.as
auth.addEventListener( KlugAuthEvent.APPLE_CREDENTIAL_STATE, function( e:KlugAuthEvent ):void {
    // e.state: authorized | revoked | notFound | transferred | unknown
    if ( e.state == "revoked" || e.state == "notFound" )
        signOut();   // your app function: the user removed the app from their Apple ID
});

var savedID:String = loadAppleUserID();   // stored after APPLE_SUCCESS; your app function
if ( auth.isSupported && savedID != "" )
    auth.getCredentialState( savedID );      // Apple only: iOS and macOS

API overview

KlugAuth.getInstance()Returns the single instance.
isSupportedTrue where Sign in with Apple is available (iOS, macOS).
isGoogleSupportedTrue where Sign in with Google is available (Android, iOS, macOS).
generateNonce()Static. A fresh random nonce (32 bytes as hex); use it once and send the same value to your server.
signInWithApple(nonce)Opens Apple's sign-in sheet. Returns false if it could not start (not supported, or a sign-in is already running).
signInWithGoogle(clientId, nonce)Opens Google sign-in. Android: the web client ID; iOS / macOS: the iOS client ID. Returns false if it could not start.
getCredentialState(userID)Asks Apple whether the user is still authorized; the answer arrives as APPLE_CREDENTIAL_STATE. iOS and macOS.
KlugAuthEventidentityToken, authorizationCode, userID, email, givenName, familyName, fullName, state, errorCode, errorMessage.

Events

APPLE_SUCCESSidentityToken, authorizationCode, userID; email and names only on the first authorization.
APPLE_CANCELEDThe user closed the sheet.
APPLE_ERRORerrorCode and errorMessage from the system.
APPLE_CREDENTIAL_STATEuserID and state: authorized · revoked · notFound · transferred · unknown
GOOGLE_SUCCESSidentityToken, userID (the account e-mail), email, givenName, familyName.
GOOGLE_CANCELEDThe user closed the sheet.
GOOGLE_ERRORerrorCode and errorMessage; on Android NO_ACCOUNT when the device has no Google account.

Buy KlugAuth

A yearly licence for one AIR application, with all updates for 12 months. After payment you receive the extension, the ActionScript library and the documentation by e-mail, usually within one business day. Licence and terms

Simple
€9 / year
  • Licence for one AIR application
  • All updates for 12 months
  • No support
Buy Simple
Standard
€39 / year
  • Licence for one AIR application
  • All updates for 12 months
  • Answer by e-mail within 7 days
Buy Standard
Priority
€79 / year
  • Licence for one AIR application
  • All updates for 12 months
  • Answer by e-mail within 48 hours
Buy Priority
Taxes are calculated at checkout by Link (Stripe). You enter the application ID of your AIR app during checkout.

Requirements

AIR SDK51.x (HARMAN)
iOSiOS 13 or later
AndroidAndroid 6 or later, Google Play services
macOSmacOS 10.15 or later
AppleSign in with Apple capability on your App ID
GoogleOAuth clients in the Google Cloud console