← 모든 확장

네이티브 확장

KlugAuth

com.klug.auth.KlugAuth

APM이 필요 없습니다. 다운로드해서 바로 사용하세요. 이보다 더 간단할 수 없습니다.

ActionScript에서 시스템 로그인 시트를 통해 Sign in with Apple과 Sign in with Google을 사용할 수 있습니다. 앱은 서버용 검증된 ID 토큰을 받으므로, 사용자는 비밀번호를 만들지 않고도 계정을 만듭니다.

iOSAndroidmacOSMac의 iPad 프로덕션 운영 중 연 €19부터 · 구매

개요

대부분의 사용자는 등록 양식에서 포기합니다: 사용자 이름, 기억해야 하는 비밀번호, 스팸함으로 들어가는 이메일 코드. KlugAuth를 쓰면 Apple로 계속하기 또는 Google로 계속하기를 탭하는 것으로 끝납니다.

KlugAuth는 각 플랫폼의 네이티브 로그인을 표시합니다. iOS와 macOS에서는 Face ID / Touch ID를 사용하는 Apple 시트, Google에는 Android 계정 시트(Credential Manager), iOS와 macOS의 Google에는 시스템 로그인 창을 사용합니다. 서버에서 검증할 수 있도록 공급자의 ID 토큰을 nonce와 함께 반환하며, 계정이 삭제될 때 연동을 해제하는 데 필요한 Apple 인증 코드도 함께 제공합니다(App Store 가이드라인 5.1.1(v)).

Google SDK는 포함되어 있지 않습니다. iOS와 macOS의 Google 로그인은 시스템 브라우저 시트에서 PKCE를 사용하는 표준 OAuth 흐름을 사용하므로 확장이 작게 유지됩니다.

KlugAuth는 Apple 또는 Google을 이용한 등록, 로그인, 기기 로그아웃 확인에 사용되며, 개념 증명인 저희 앱의 현재 릴리스에서 실행됩니다.

기능

  • 독립형: ANE 하나로 충분하며, 코어 라이브러리나 의존성 ANE를 추가할 필요가 없음
  • iOS 13 이상, macOS 10.15 이상, Apple silicon Mac의 iPad 앱에서 Sign in with Apple
  • Android(Credential Manager)와 iOS / macOS(시스템 로그인 창, Google SDK 없음)에서 Sign in with Google
  • ID 토큰, 사용자 ID, 이메일, 이름. 갱신과 해제를 위한 Apple 인증 코드
  • 재전송 공격 방지를 위한 nonce 도우미(Apple은 SHA-256, Google은 원본 값을 전달)
  • 재방문 사용자를 위한 Apple 자격 증명 상태 확인(authorized / revoked)
  • 성공, 취소, 오류 이벤트가 분리되어 있으며, 취소는 오류가 아닌 취소로 보고

지원 플랫폼

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

Android에서의 Sign in with Apple은 Apple의 웹 흐름과 작은 서버 페이지로 가능하며, 프로젝트의 일부로 제공해 드릴 수 있습니다. isSupported(Apple)와 isGoogleSupported가 기기가 제공하는 기능을 코드에 알려 줍니다.

시작하기

애플리케이션 디스크립터에 확장을 추가합니다:

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

Sign in with Apple을 쓰려면 entitlement를 추가하세요(iOS: 디스크립터의 Entitlements, macOS: 서명 시):

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

Google의 경우 Google Cloud 콘솔에서 OAuth 클라이언트를 만드세요: 웹 클라이언트(ID가 Android에서의 토큰 audience), 패키지 이름과 SHA-1을 가진 Android 클라이언트, iOS와 macOS용 iOS 클라이언트.

코드 예제

버튼부터 서버까지 다섯 가지 완전한 흐름입니다. 모든 호출은 즉시 반환되며, 결과는 KlugAuthEvent로 전달됩니다. 전체 문서 →

1 · 기기가 지원하는 방식 제공
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 · 취소와 오류
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 · 재방문 Apple 사용자 확인
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 개요

KlugAuth.getInstance()단일 인스턴스를 반환합니다.
isSupportedSign in with Apple을 사용할 수 있는 곳(iOS, macOS)에서 true입니다.
isGoogleSupportedSign in with Google을 사용할 수 있는 곳(Android, iOS, macOS)에서 true입니다.
generateNonce()정적 메서드입니다. 새로운 무작위 nonce(16진수 32바이트)이며, 한 번만 사용하고 같은 값을 서버로 보내세요.
signInWithApple(nonce)Apple의 로그인 시트를 엽니다. 시작하지 못하면(지원되지 않거나 이미 로그인이 진행 중) false를 반환합니다.
signInWithGoogle(clientId, nonce)Google 로그인을 엽니다. Android: 웹 클라이언트 ID, iOS / macOS: iOS 클라이언트 ID. 시작하지 못하면 false를 반환합니다.
getCredentialState(userID)사용자가 여전히 인증된 상태인지 Apple에 묻고, 응답은 APPLE_CREDENTIAL_STATE로 도착합니다. iOS와 macOS.
KlugAuthEventidentityToken, authorizationCode, userID, email, givenName, familyName, fullName, state, errorCode, errorMessage.

이벤트

APPLE_SUCCESSidentityToken, authorizationCode, userID; email 과 이름은 최초 인증 시에만 제공됩니다.
APPLE_CANCELED사용자가 시트를 닫았습니다.
APPLE_ERRORerrorCode 및 errorMessage는 시스템에서 전달됩니다.
APPLE_CREDENTIAL_STATEuserID 및 state: authorized · revoked · notFound · transferred · unknown
GOOGLE_SUCCESSidentityToken, userID (계정 이메일), email, givenName, familyName.
GOOGLE_CANCELED사용자가 시트를 닫았습니다.
GOOGLE_ERRORerrorCode 및 errorMessage. Android에서는 기기에 Google 계정이 없을 때 NO_ACCOUNT가 반환됩니다.

KlugAuth 구매

AIR 애플리케이션 1개에 대한 연간 라이선스이며 12개월간 모든 업데이트를 제공합니다. 결제 후 확장, ActionScript 라이브러리, 문서를 이메일로 보내 드리며, 보통 영업일 기준 1일 이내입니다. 라이선스 및 약관

심플
€19 / 년
  • AIR 애플리케이션 1개에 대한 라이선스
  • 12개월간 모든 업데이트
  • 지원 없음
심플 구매
스탠더드
€149 / 년
  • AIR 애플리케이션 1개에 대한 라이선스
  • 12개월간 모든 업데이트
  • 7일 이내 이메일 답변
스탠더드 구매
프라이어리티
€299 / 년
  • AIR 애플리케이션 1개에 대한 라이선스
  • 12개월간 모든 업데이트
  • 48시간 이내 이메일 답변
프라이어리티 구매
세금은 Link(Stripe)가 결제 시 계산합니다. 결제 중에 AIR 앱의 애플리케이션 ID를 입력합니다.

요구 사항

AIR SDK51.x (HARMAN)
iOSiOS 13 이상
AndroidAndroid 6 이상, Google Play services
macOSmacOS 10.15 이상
AppleApp ID의 Sign in with Apple capability
GoogleGoogle Cloud 콘솔의 OAuth 클라이언트