question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

QuickLogin: AuthorizationCode is null

See original GitHub issue

As a follow-up to https://github.com/lupidan/apple-signin-unity/issues/132, which could be resolved by using version 1.4.2, I am still facing a problem with the QuickLogin under iOS 15.1:

My code now throws an NRE because appleIdCredential.AuthorizationCode is null (previously, it was always set). Note that IdentityToken is available (not null). Just the AuthorizationCode is null.

I also noticed that - if that happens - AuthorizationCode is still null when I then try to login with the regular login, i.e. without using QuickLogin. Only if I restart the app completely, skip the QuickLogin and then use the regular Apple login, the AuthorizationCode returns a value again.

So it seems as if QuickLogin won’t deliver an authorization code anymore, which basically breaks the functionality, as I need both tokens to login to my app. 😕

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
bhupiistercommented, Feb 16, 2022

I came around same issue. Authorization code was null when using QuickLogin after using LoginWithAppleId. I am using it to authenticate firebase and luckily firebase is ok with AuthorizationCode being null. Firebase.Auth.Credential credential = Firebase.Auth.OAuthProvider.GetCredential("apple.com", appleIdToken, rawNonce, null); Firebase GetCredential Documentation AuthorizationCode will only be passed once, as @lupidan said. @lupidan I would suggest you to modify your firebase example with unity and make 4th parameter of GetCredential as null.

I’ll leave a code for anyone wanting help on linking firebase with Apple ID

Spoiler: I am making a guest account first and then linking it with the Apple ID(Firebase) because of my game logic. You can use SignInWithCredentialAsync instead of LinkAndRetrieveDataWithCredentialAsync

public void SignInWithAppleID()//Sing in with apple Button command here
{
    SignInWithAppleID(userReceived =>
    {
        if (userReceived != null)
        {
            user = userReceived;//If everything is successful, this will be current logged in firebase user.
            Debug.Log(user.UserId);//This will give firebase userid
        }
        else
        {
            //Failed to receive firebase user
        }
    });
}
public void SignInWithAppleID(Action<FirebaseUser> firebaseAuthCallback)
{

    string rawNonce = GenerateRandomString(32);//See lupidan example for this function
    string nonce = GenerateSHA256NonceFromRawNonce(rawNonce);//See lupidan example for this function
    AppleAuthQuickLoginArgs quickLoginArgs = new AppleAuthQuickLoginArgs(nonce);

    // Quick login should succeed if the credential was authorized before and not revoked
    appleAuthManager.QuickLogin(quickLoginArgs, credential =>
    {
        var appleIdCredential = credential as IAppleIDCredential;
        if (appleIdCredential != null)
        {
            // If it's an Apple credential, save the user ID, for later logins
            PlayerPrefs.SetString(AppleUserIdKey, credential.User);            
            PerformFirebaseAuthentication(appleIdCredential, rawNonce, firebaseAuthCallback);
        }
    },
    error =>
    {
        // If Quick Login fails, we should show the normal sign in with apple menu, to allow for a normal Sign In with apple
        var authorizationErrorCode = error.GetAuthorizationErrorCode();
        Debug.LogWarning("Quick Login Failed " + authorizationErrorCode.ToString() + " " + error.ToString());
        SignInWithApple(userReceived =>
        {
            user = userReceived;
            if (user != null)
            {
                firebaseAuthCallback(user);
            }
            else
            {
                //Firebase auth was cancelled or failed
                firebaseAuthCallback(null);
            }
        });
    });
}

private void SignInWithApple(Action<FirebaseUser> firebaseAuthCallback)
{
    string rawNonce = GenerateRandomString(32);
    string nonce = GenerateSHA256NonceFromRawNonce(rawNonce);
    AppleAuthLoginArgs loginArgs = new AppleAuthLoginArgs(LoginOptions.IncludeEmail | LoginOptions.IncludeFullName, nonce);

    this.appleAuthManager.LoginWithAppleId(loginArgs, credential =>
    {
        // If a sign in with apple succeeds, we should have obtained the credential with the user id, name, and email, save it
        var appleIdCredential = credential as IAppleIDCredential;
        if (appleIdCredential != null)
        {
            PlayerPrefs.SetString(AppleUserIdKey, credential.User);
            PerformFirebaseAuthentication(appleIdCredential, rawNonce, firebaseAuthCallback);
        }
    },
    error =>
    {
        var authorizationErrorCode = error.GetAuthorizationErrorCode();
        Debug.LogWarning("Sign in with Apple failed " + authorizationErrorCode.ToString() + " " + error.ToString());
        firebaseAuthCallback(null);
    });
}

private void PerformFirebaseAuthentication(IAppleIDCredential appleIdCredential, string rawNonce, Action<FirebaseUser> firebaseAuthCallback)
{
    string identityToken = "";
    string authorizationCode = "";
    if (appleIdCredential.IdentityToken != null)
    {
        identityToken = Encoding.UTF8.GetString(appleIdCredential.IdentityToken, 0, appleIdCredential.IdentityToken.Length);
    }
    else
    {
        firebaseAuthCallback(null);//Return null if identityToken is null as we cannot proceed without it.
    }
    if (appleIdCredential.AuthorizationCode != null)//This will not be null for the first time, for all subsequent calls, it will return null.
    {
        authorizationCode = Encoding.UTF8.GetString(appleIdCredential.AuthorizationCode, 0, appleIdCredential.AuthorizationCode.Length);
    }
    else
    {
        //If Authorization code is null, proceed without it and make it the string null. Firebase does not require it.
        authorizationCode = null;
    }
    Credential credential = OAuthProvider.GetCredential("apple.com", identityToken, rawNonce, authorizationCode);//authorizationCode can be null
    auth.CurrentUser.LinkAndRetrieveDataWithCredentialAsync(credential).ContinueWithOnMainThread(task =>
    {
        if (task.IsCanceled)
        {
            //Task is cancelled
            firebaseAuthCallback(null);
        }
        else if (task.IsFaulted)
        {
            //Task is faulted
            Debug.LogError("linkAsync encountered an error: " + task.Exception);     
            firebaseAuthCallback(null);
           
        }
        else if (task.IsCompleted)
        {               
            firebaseAuthCallback(auth.CurrentUser);        
        }        
    });

}
1reaction
lupidancommented, Nov 13, 2021

Yeah, my initial conclusion about this, is that apple just wants you to use that Authorization Code once, to get a refresh token every day, and check if the user is still valid or they have somehow revoked credentials. So it could make sense you only get it once the first time a user signs in ¿?

I’m glad to hear you sorted it out in your backend. Unfortunately there is not much we can do besides ask in the official Apple forum if this is a bug, or the expected behaviour 🤷

Closing this

Read more comments on GitHub >

github_iconTop Results From Across the Web

LinkedIn OAuth2 Authorization Code is empty
Only an empty code parameter, and the state parameter (which is not empty and seems ok). Has anyone encountered this issue? What should...
Read more >
Sign in with Apple Unity Plugin v1.4.2 [Unofficial]
Supports Get Credential status (Authorized, Revoked and Not Found). Supports Quick login (including iTunes Keychain credentials). Supports ...
Read more >
unity3d: wits end on getting sign in with apple to work
AuthorizationError Code=1001 "(null)" code-block Debug.Log("0802 inside quick login"); var quickLoginArgs = new AppleAuthQuickLoginArgs(); ...
Read more >
Custom OAuth returns Invalid authorization code
The logs show successful login but a failed exchange of “Invalid Authorization Code” for “All Applications”, so it appears to my untrained ...
Read more >
Getting Invalid authorization code Error
This error can happen for a few reasons. The provided authorization code could be invalid, expired, revoked, does not match the redirection URI ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found