Unity中Apple Sign In对接Firebase Auth时ID Token解析失败求助
Unity中Apple Sign In对接Firebase Auth时ID Token解析失败问题
问题描述
对接过程中出现以下错误:
Failed to sign in with Firebase using Apple credentials: One or more errors occurred. (Unable to parse the ID Token.)
开发环境:macOS平台,Unity,Firebase SDK版本11.2,已声明public FirebaseAuth auth和public FirebaseUser User对象。
登录实现代码
private void SignInWithApple() { var rawNonce = GenerateRandomString(32); nonce1 = GenerateSHA256NonceFromRawNonce(rawNonce); var loginArgs = new AppleAuthLoginArgs(LoginOptions.IncludeEmail | LoginOptions.IncludeFullName , nonce1 ); Debug.Log("Apple login is being initiated."); this._appleAuthManager.LoginWithAppleId( loginArgs, async credential => { Debug.Log("Credential is being obtained."); if (credential is IAppleIDCredential appleIdCredential) { var authorizationCode = Encoding.UTF8.GetString(appleIdCredential.AuthorizationCode); PlayerPrefs.SetString(AppleUserIdKey, appleIdCredential.User); var identityToken = System.Convert.ToBase64String(appleIdCredential.IdentityToken); Debug.Log($"Apple login information is being transferred to Firebase credential. identityToken: {identityToken}"); var appleCredential = OAuthProvider.GetCredential("apple.com", identityToken, nonce1, null); Debug.Log($"Apple login information has been transferred to Firebase credential. {appleCredential}"); try { var firebaseUser = await auth.SignInWithCredentialAsync(appleCredential); AddStatusText($"Firebase user info: Email = {firebaseUser.Email}, Id = {firebaseUser.UserId}, Name = {firebaseUser.DisplayName}"); Debug.Log("Firebase user info: Email = " + firebaseUser.Email + ", Id = " + firebaseUser.UserId + ", Name = " + firebaseUser.DisplayName); Debug.Log($"Apple login information has been transferred to Firebase credential."); StartCoroutine(InitializeNewUserData(firebaseUser.Email, firebaseUser.DisplayName, "AppleLogin")); StartCoroutine(InitializeFirebaseCoroutine()); } catch (Exception e) { Debug.LogError("Failed to sign in with Firebase using Apple credentials: " + e.Message); } } }, error => { var authorizationErrorCode = error.GetAuthorizationErrorCode(); Debug.LogWarning("Sign in with Apple failed. Error: " + authorizationErrorCode.ToString() + " " + error.ToString()); }); }
Nonce生成代码
public static string GenerateRandomString(int length) { if (length <= 0) { throw new Exception("Expected nonce to have positive length"); } const string charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._"; var cryptographicallySecureRandomNumberGenerator = new RNGCryptoServiceProvider(); var result = string.Empty; var remainingLength = length; var randomNumberHolder = new byte[1]; while (remainingLength > 0) { var randomNumbers = new List<int>(16); for (var randomNumberCount = 0; randomNumberCount < 16; randomNumberCount++) { cryptographicallySecureRandomNumberGenerator.GetBytes(randomNumberHolder); randomNumbers.Add(randomNumberHolder[0]); } for (var randomNumberIndex = 0; randomNumberIndex < randomNumbers.Count; randomNumberIndex++) { if (remainingLength == 0) { break; } var randomNumber = randomNumbers[randomNumberIndex]; if (randomNumber < charset.Length) { result += charset[randomNumber]; remainingLength--; } } } return result; } private static string GenerateSHA256NonceFromRawNonce(string rawNonce) { var sha = new SHA256Managed(); var utf8RawNonce = Encoding.UTF8.GetBytes(rawNonce); var hash = sha.ComputeHash(utf8RawNonce); var result = string.Empty; for (var i = 0; i < hash.Length; i++) { result += hash[i].ToString("x2"); } return result; }
Xcode错误日志
<<SignInWithApple>b__49_0>d:MoveNext() System.Runtime.CompilerServices.AsyncVoidMethodBuilder:Start(TStateMachine&) FirebaseModules:<SignInWithApple>b__49_0(ICredential) AppleAuth.CallbackHandler:ExecutePendingCallbacks() Firebase.Auth.Credential <<SignInWithApple>b__49_0>d:MoveNext() System.Runtime.CompilerServices.AsyncVoidMethodBuilder:Start(TStateMachine&) FirebaseModules:<SignInWithApple>b__49_0(ICredential) AppleAuth.CallbackHandler:ExecutePendingCallbacks() Failed to sign in with Firebase using Apple credentials: One or more errors occurred. (Unable to parse the ID Token.) <<SignInWithApple>b__49_0>d:MoveNext() System.Threading.ExecutionContext:RunInternal(ExecutionContext, ContextCallback, Object, Boolean) System.Runtime.CompilerServices.MoveNextRunner:Run() UnityEngine.WorkRequest:Invoke() UnityEngine.UnitySynchronizationContext:Exec()
修复方案
1. 修正ID Token的获取方式
Apple返回的IdentityToken已经是URL安全的Base64编码字符串,无需二次编码。修改代码中获取identityToken的行:
// 替换原代码行 var identityToken = System.Text.Encoding.UTF8.GetString(appleIdCredential.IdentityToken);
2. 验证Nonce处理逻辑
- 确认
GenerateSHA256NonceFromRawNonce方法生成的是小写十六进制字符串(已符合要求) - 确保传递给Apple的nonce是原始随机字符串的SHA256哈希,而非原始字符串
3. 检查Firebase与Apple开发者后台配置
- Firebase控制台中开启Apple登录提供商,配置正确的Team ID、服务ID和签名证书
- Apple开发者后台中,对应服务ID已启用Sign In with Apple,回调URL与Firebase配置一致
4. 验证ID Token格式
使用JWT解析工具检查获取到的identityToken是否为有效的JWT格式,确认包含iss(应为https://appleid.apple.com)、sub等必要字段,且签名有效。
5. 确保异步回调在主线程执行
Unity中Firebase的异步回调可能在后台线程触发,使用UnityMainThreadDispatcher或手动切换到主线程处理登录后的逻辑,避免线程问题导致的解析错误。
内容的提问来源于stack exchange,提问作者user22269958
相关产品推荐
相关产品推荐

