ios - 将 'IDToken' 替换为 'idToken' Swift Sign in with Apple using Firebase
问题描述
我正在尝试使用 Firebase 使用 Apple 登录。Firebase 文档说要使用let credential = OAuthProvider.credential(withProviderID: "apple.com", IDToken: idTokenString, rawNonce: nonce)
,但是 Xcode 给出了错误并提出了修复建议。
如果我遵循 Xcode 的建议,应用程序会崩溃并显示Invalid state: A login callback was received, but no login request was sent.
. 我已经在 Stack Overflow 上看到了与此相关的所有其他问题,但没有一个能解决问题。这是当前版本的 Firebase SDK 的问题还是我的错误。
解决方案
试试我的代码,它对我有用
import CryptoKit
import Firebase
import AuthenticationServices
extension SocietyLoginViewController {
@available(iOS 13, *)
func appleLogin() {
let nonce = randomNonceString()
currentNonce = nonce
let appleIDProvider = ASAuthorizationAppleIDProvider()
let request = appleIDProvider.createRequest()
request.requestedScopes = [.fullName, .email]
request.nonce = sha256(nonce)
let authorizationController = ASAuthorizationController(authorizationRequests: [request])
authorizationController.delegate = self
authorizationController.presentationContextProvider = self
authorizationController.performRequests()
}
@available(iOS 13, *)
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()
return hashString
}
// Adapted from https://auth0.com/docs/api-auth/tutorials/nonce#generate-a-cryptographically-random-nonce
func randomNonceString(length: Int = 32) -> String {
precondition(length > 0)
let charset: Array<Character> = Array("0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._")
var result = ""
var remainingLength = length
while remainingLength > 0 {
let randoms: [UInt8] = (0 ..< 16).map { _ in
var random: UInt8 = 0
let errorCode = SecRandomCopyBytes(kSecRandomDefault, 1, &random)
if errorCode != errSecSuccess {
fatalError("Unable to generate nonce. SecRandomCopyBytes failed with OSStatus \(errorCode)")
}
return random
}
randoms.forEach { random in
if remainingLength == 0 {
return
}
if random < charset.count {
result.append(charset[Int(random)])
remainingLength -= 1
}
}
}
return result
}
}
@available(iOS 13.0, *)
extension SocietyLoginViewController: ASAuthorizationControllerDelegate , ASAuthorizationControllerPresentationContextProviding {
func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
return self.view.window!
}
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 {
return
}
guard let idTokenString = String(data: appleIDToken, encoding: .utf8) else {
return
}
// Initialize a Firebase credential.
let credential = OAuthProvider.credential(withProviderID: "apple.com", idToken: idTokenString, rawNonce: nonce)
// Sign in with Firebase.
}
}
func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
// Handle error.
print("Sign in with Apple errored: \(error)")
}
}
推荐阅读
- python - 如何修复 Python 中的 Opencv ValueError?
- c++ - 如何解析 char 数组索引(C++)
- python - 将 pandas 数据帧变量从 google 计算引擎保存到 csv 到 google 存储桶,而无需先保存到磁盘
- javascript - 带折线的 TextArea 值
- python - 如何计算字符串中元音的总数
- python - Pandas 索引和计算行效率想法矢量化代码
- c++ - 具有构造函数的另一个类中的对象数组
- typescript - Jest Async/Await 无论如何都会失败回调?打字稿
- .net - 是否可以在单个解决方案中创建多个设置项目
- flutter - Flutter 应用程序在离开新闻 api 屏幕并返回时冻结