[Bug] iOS: OAuthProvider::GetCredential with raw_nonce and null access_token sends empty access_token, Sign in with Apple fails with "Invalid OAuth response from apple.com"
維護者通常 2 天內回覆
還沒有人認領這個 Issue。
評估
- 難度
- 2/5
- 預估耗時
- 1-3 小時
- 新手友好度
- 82/100
- Issue 類型
- 缺陷
- 描述清晰度
- 描述清楚
- 活躍度
- 活躍
- 技術堆疊
- cpp, ios, objective-c
研究方向
從 auth/src/ios/credential_ios.mm 開始,並比較 issue 中描述的 iOS 憑證選擇器。檢查 4 參數的 GetCredential 呼叫如何處理 null access_token。完成標準是:在這種情況下使用不帶 access_token 的選擇器,讓請求不包含空的 access_token,並且 Apple 登入能夠成功。
由索引模型根據 Issue 內容生成。
描述
[REQUIRED] Please fill in the following fields:
- Pre-built SDK from the website or open-source from this repo: Pre-built SDK from the website (
firebase_cpp_sdk_13.13.0.zip) - Firebase C++ SDK version: 13.13.0. The same code is in 13.13.1, 14.0.0, 14.1.0 and
main. - Problematic Firebase Component: Auth
- Other Firebase Components in use: App, Firestore, Functions, Analytics, Crashlytics, Remote Config, Storage, Database
- Platform you are using the C++ SDK on: Mac
- Platform you are targeting: iOS (Firebase iOS SDK 12.19.1, iPhone 13)
[REQUIRED] Please describe the issue here:
On iOS, Sign in with Apple always fails when the credential comes from OAuthProvider::GetCredential(provider_id, id_token, raw_nonce, access_token) with access_token == nullptr, as the Apple C++ guide recommends. Both Auth::SignInAndRetrieveDataWithCredential and User::LinkWithCredential return:
error 4 (kAuthErrorInvalidCredential): "Invalid OAuth response from apple.com"
The backend reply is INVALID_IDP_RESPONSE : Invalid OAuth response from apple.com.
Root cause
auth/src/ios/credential_ios.mm passes nil when access_token is null:
NSString* access_token_string =
(access_token != nullptr) ? util::CStringToNSString(access_token) : nullptr;
FIRAuthCredential* credential =
(FIRAuthCredential*)[FIROAuthProvider credentialWithProviderID:@(provider_id)
IDToken:@(id_token)
rawNonce:@(raw_nonce)
accessToken:access_token_string];
Since the Swift rewrite of FirebaseAuth (iOS SDK 11+), this selector's accessToken is a non-optional String. See FirebaseAuth/Sources/Swift/AuthProvider/OAuthProvider.swift:
@objc(credentialWithProviderID:IDToken:rawNonce:accessToken:)
public static func credential(withProviderID providerID: String, idToken: String,
rawNonce: String,
accessToken: String) -> OAuthCredential
Passing nil from Objective-C into a non-optional Swift String bridges to an empty string. OAuthCredential then sets providerAccessToken = "", and the verifyAssertion / signInWithIdp post body includes access_token=. The backend tries to validate the empty access token against apple.com and rejects the request.
The iOS SDK already has a selector for this case: credentialWithProviderID:IDToken:rawNonce:, which takes no access token. Apple also has its own factory: appleCredentialWithIDToken:rawNonce:fullName:.
Evidence
We logged the Apple identity token and raw nonce on the device, then sent them straight to accounts:signInWithIdp over REST:
postBody |
Result |
|---|---|
id_token=…&providerId=apple.com&nonce=<raw> |
200 OK (sign-in and link both work) |
id_token=…&access_token=&providerId=apple.com&nonce=<raw> |
400 INVALID_IDP_RESPONSE : Invalid OAuth response from apple.com, the same error the C++ SDK returns |
id_token=…&providerId=apple.com |
400 MISSING_OR_INVALID_NONCE : Nonce is missing in the request. |
The token is valid: iss = https://appleid.apple.com, aud = <bundle id>, and nonce equals the SHA-256 of the raw nonce. The project is configured correctly, because the same token succeeds without access_token=.
Suggested fix
In auth/src/ios/credential_ios.mm, use the no-access-token selector when access_token is null:
Credential OAuthProvider::GetCredential(const char* provider_id, const char* id_token,
const char* raw_nonce, const char* access_token) {
FIREBASE_ASSERT_RETURN(Credential(), provider_id && id_token && raw_nonce);
FIRAuthCredential* credential =
access_token != nullptr
? (FIRAuthCredential*)[FIROAuthProvider credentialWithProviderID:@(provider_id)
IDToken:@(id_token)
rawNonce:@(raw_nonce)
accessToken:@(access_token)]
: (FIRAuthCredential*)[FIROAuthProvider credentialWithProviderID:@(provider_id)
IDToken:@(id_token)
rawNonce:@(raw_nonce)];
return Credential(new FIRAuthCredentialPointer(credential));
}
This only affects the 4-argument overload. The 3-argument GetCredential(provider_id, id_token, access_token) asserts that access_token is non-null, so it never passes nil.
Steps to reproduce:
Have you been able to reproduce this issue with just the Firebase C++ quickstarts ?
Not tried with the quickstart. We reproduced it in our own app and with the minimal code below.
What's the issue repro rate? (eg 100%, 1/5 etc)
100% on a real device.
What happened? How can we make the problem occur?
- Enable the Apple provider in the Firebase console. Add the
com.apple.developer.applesigninentitlement to the iOS app. - Run
ASAuthorizationAppleIDProviderwithrequest.nonce = SHA256(rawNonce). - Take
identityTokenfrom the returnedASAuthorizationAppleIDCredential. - Call
OAuthProvider::GetCredential("apple.com", idToken, rawNonce, nullptr), thenSignInAndRetrieveDataWithCredentialorLinkWithCredential. - The future completes with error 4,
"Invalid OAuth response from apple.com". Noapple.comuser is created.
Relevant Code:
// Objective-C++ on iOS, after ASAuthorizationController succeeds
ASAuthorizationAppleIDCredential *apple = (ASAuthorizationAppleIDCredential *)authorization.credential;
NSString *idToken = [[NSString alloc] initWithData:apple.identityToken encoding:NSUTF8StringEncoding];
firebase::auth::Credential credential = firebase::auth::OAuthProvider::GetCredential(
"apple.com", idToken.UTF8String, rawNonce.UTF8String, /*access_token=*/nullptr);
// Either call fails with kAuthErrorInvalidCredential: "Invalid OAuth response from apple.com"
auth->SignInAndRetrieveDataWithCredential(credential);
auth->current_user().LinkWithCredential(credential);
- 主要語言
- C++
- 星號
- 325
- 分支
- 137
- 平均合併
- 2 天 20 小時
- 30 天內合併 PR
- 15
環境準備
- 沒有 Dockerfile 或 Docker Compose 檔案
- 有 Pull Request 範本
- 閱讀貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
firebase/firebase-cpp-sdk 的其他 Issue
-
new type: question
難度 2/5 1-3 小時 新手友好度 85/100
firebase/firebase-cpp-sdk#1926 ·
維護者通常 2 天內回覆
-
難度 2/5 1-3 小時 新手友好度 72/100
firebase/firebase-cpp-sdk#1905 · 2 則留言 ·
維護者通常 2 天內回覆
-
[Database][Android] SIGSEGV in Database::DeleteInternal when embedded bridge-class init fails; FindClassInFiles passes JNI-form names to loadClass on Android可能已有人在做 關聯的 PR 仍在進行中或已合併。 未關閉
難度 3/5 半天 新手友好度 55/100
firebase/firebase-cpp-sdk#1936 · 3 則留言 ·
維護者通常 2 天內回覆
-
難度 4/5 3-5 天 新手友好度 55/100
firebase/firebase-cpp-sdk#1935 ·
維護者通常 2 天內回覆
-
api: firestore
難度 5/5 一週以上 新手友好度 35/100
firebase/firebase-cpp-sdk#1920 · 3 則留言 ·
維護者通常 2 天內回覆
查看 firebase/firebase-cpp-sdk 的全部 Issue
相似的 Issue
-
documentation enhancement
難度 2/5 1-3 小時 新手友好度 68/100
維護者通常 1 天內回覆
-
enhancement
難度 2/5 1-3 小時 新手友好度 70/100
QuantStack/git2cpp#203 ·
維護者通常 1 天內回覆
-
bug
難度 2/5 1-3 小時 新手友好度 65/100
BaptisteHudyma/Lamp-Da#588 ·
維護者通常 1 天內回覆
-
bug macOS networking
難度 2/5 1-3 小時 新手友好度 78/100
維護者通常 2 天內回覆
-
難度 2/5 1-3 小時 新手友好度 85/100
docling-project/docling-parse#448 ·
維護者通常 5 天內回覆