在 iOS 13 上的 Swift 中使用 Apple for Firebase 设置登录时出错的原因是啥?
Posted
技术标签:
【中文标题】在 iOS 13 上的 Swift 中使用 Apple for Firebase 设置登录时出错的原因是啥?【英文标题】:Cause of error setting up Sign in with Apple for Firebase in Swift on iOS 13?在 iOS 13 上的 Swift 中使用 Apple for Firebase 设置登录时出错的原因是什么? 【发布时间】:2020-03-19 12:48:29 【问题描述】:我一直在关注https://firebase.google.com/docs/auth/ios/apple,它确实提到了我收到的错误“将 SHA256 哈希随机数作为十六进制字符串发送”,但它没有提供任何帮助来解决它,而且我的搜索没有给出我有一个可行的解决方案。
我的视图控制器代码提取是
fileprivate var currentNonce: String?
@objc @available(iOS 13, *)
func startSignInWithAppleFlow()
let nonce = randomNonceString()
currentNonce = nonce
let appleIDProvider = ASAuthorizationAppleIDProvider()
let request = appleIDProvider.createRequest()
request.requestedScopes = [.fullName, .email]
request.nonce = sha256(nonce)
print(request.nonce)
let authorizationController = ASAuthorizationController(authorizationRequests: [request])
authorizationController.delegate = self
authorizationController.presentationContextProvider = self
authorizationController.performRequests()
@available(iOS 13, *)
private func sha256(_ input: String) -> String
let inputData = Data(input.utf8)
let hashedData = SHA256.hash(data: inputData)
let hashString = hashedData.compactMap
return String(format: "%02x", $0)
.joined()
print(hashString)
return hashString
@available(iOS 13.0, *)
extension LoginViewController: ASAuthorizationControllerDelegate
func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization)
if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential
guard let nonce = currentNonce else
fatalError("Invalid state: A login callback was received, but no login request was sent.")
guard let appleIDToken = appleIDCredential.identityToken else
print("Unable to fetch identity token")
return
guard let idTokenString = String(data: appleIDToken, encoding: .utf8) else
print("Unable to serialize token string from data: \(appleIDToken.debugDescription)")
return
// Initialize a Firebase credential.
print(nonce)
let credential = OAuthProvider.credential(withProviderID: "apple.com",
idToken: idTokenString,
accessToken: nonce)
print(credential)
// Sign in with Firebase.
Auth.auth().signInAndRetrieveData(with: credential) (authResult, error) in
if (error != nil)
// Error. If error.code == .MissingOrInvalidNonce, make sure
// you're sending the SHA256-hashed nonce as a hex string with
// your request to Apple.
print(authResult)
print(error!)
print(error!.localizedDescription)
return
// User is signed in to Firebase with Apple.
// ...
此部分与网页上的说明不同,因为 Xcode 出错了
let credential = OAuthProvider.credential(withProviderID: "apple.com",
idToken: idTokenString,
accessToken: nonce)
如果我在之前打印随机数
let credential = OAuthProvider.credential(withProviderID: "apple.com",
idToken: idTokenString,
accessToken: nonce)
我得到 2eNjrtagc024_pd3wfnt_PZ0N89GZ_b6_QJ3IZ_
response.nonce 值为 cd402f047012a2d5c129382c56ef121b53a679c0a5c5e37433bcde2967225afe
显然这些不一样,但我似乎无法弄清楚我做错了什么。
完整的错误输出是
Error Domain=FIRAuthErrorDomain Code=17999 "An internal error has occurred, print and inspect the error details for more information." UserInfo=NSUnderlyingError=0x60000388a820 Error Domain=FIRAuthInternalErrorDomain Code=3 "(null)" UserInfo=FIRAuthErrorUserInfoDeserializedResponseKey=
code = 400;
errors = (
domain = global;
message = "MISSING_OR_INVALID_NONCE : Nonce is missing in the request.";
reason = invalid;
);
message = "MISSING_OR_INVALID_NONCE : Nonce is missing in the request.";
, FIRAuthErrorUserInfoNameKey=ERROR_INTERNAL_ERROR, error_name=ERROR_INTERNAL_ERROR, NSLocalizedDescription=An internal error has occurred, print and inspect the error details for more information.
An internal error has occurred, print and inspect the error details for more information.
【问题讨论】:
【参考方案1】:我遇到了同样的错误。
解决方案: 跑吧
pod update
解释:
问题正如@ethanrj 所说。文档说要做
let credential = OAuthProvider.credential(
withProviderID: "apple.com", IDToken: appleIdToken, rawNonce: rawNonce )
但这会产生错误,Xcode 会提示以下内容(rawNonce -> accessToken):
let credential = OAuthProvider.credential(
withProviderID: "apple.com", IDToken: appleIdToken, accessToken: rawNonce )
这是因为pod install
将默认安装 FirebaseAuth 6.12,当您真正需要 6.13 时,因为新功能签名仅在那里可用。可以查看源码here。
【讨论】:
非常感谢,解决了,我自己也应该想到的!最终结果 let credential = OAuthProvider.credential(withProviderID: "apple.com", idToken: idTokenString, rawNonce: nonce, accessToken: nil)【参考方案2】:您是否可能使用了错误的凭据方法?在documentation 上,看起来采用随机数的是:
let credential = OAuthProvider.credential( withProviderID: "apple.com", IDToken: appleIdToken, rawNonce: rawNonce )
但是你在这里使用的那个需要一个访问令牌,不确定这是否有帮助。
【讨论】:
谢谢,但我试过了,Xcode 给出了一个红色错误并说将 rawNonce 更改为 idToken,我还检查了 pod 文件,并且在任何项目文件中从未提及 rawNonce,格式最接近的方法是我正在使用的一个。以上是关于在 iOS 13 上的 Swift 中使用 Apple for Firebase 设置登录时出错的原因是啥?的主要内容,如果未能解决你的问题,请参考以下文章
sceneDidEnterBackground 上的 URL 请求(iOS13)
如何在 Swift 5 和 iOS 13 中使用 CIFilter sunbeamsGenerator?
Firebase Twitter oAuth 回调不适用于 Swift ios13