英文:
Firebase Auth Sign In Apple revokeToken error
问题
I am implementing the Apple Login function using Firebase.
(https://firebase.google.com/docs/auth/ios/apple?hl=ko#configure_sign_in_with_apple)
The membership registration has been completed and displayed properly on the console.
The problem is the deletion of members.
Task {
do {
try await Auth.auth().revokeToken(withAuthorizationCode: authCodeString)
try await user?.delete()
self.updateUI()
} catch {
self.displayError(error)
}
}
There was an error using this code.
Task {
do {
try await Auth.auth().revokeToken(withAuthorizationCode: authCodeString)
print("Good")
} catch {
print("Error")
}
do {
try await user?.delete()
print("Good Delete")
} catch {
print("Error")
}
}
I modified 'auth.auth().revokeToken' and 'user?.delete()' to run in two steps as above code.
The error occurred in 'auth.auth().revokeToken'. However, Delete was successful and the test account was deleted from the Firebase console.
-
May I know why 'auth.auth().revokeToken' doesn't work?
-
Is there no problem if I don't do 'auth.auth().revokeToken'?
-
How can I print a 'revokeToken' error?
Below is my code.
private func deleteCurrentUser() {
do {
let nonce = try self.randomNonceString()
self.currentNonce = nonce
let appleIDProvider = ASAuthorizationAppleIDProvider()
let request = appleIDProvider.createRequest()
request.requestedScopes = [.fullName, .email]
request.nonce = self.sha256(nonce)
let authorizationController = ASAuthorizationController(authorizationRequests: [request])
authorizationController.delegate = self
authorizationController.presentationContextProvider = self
authorizationController.performRequests()
} catch {
// In the unlikely case that nonce generation fails, show error view.
print("실패")
}
}
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()
return hashString
}
private 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
}
func authorizationController(controller: ASAuthorizationController,
didCompleteWithAuthorization authorization: ASAuthorization) {
guard let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential else {
print("Unable to retrieve AppleIDCredential")
return
}
guard let _ = self.currentNonce else {
fatalError("Invalid state: A login callback was received, but no login request was sent.")
}
guard let appleAuthCode = appleIDCredential.authorizationCode else {
print("Unable to fetch authorization code")
return
}
guard let authCodeString = String(data: appleAuthCode, encoding: .utf8) else {
print("Unable to serialize auth code string from data: \(appleAuthCode.debugDescription)")
return
}
let user = FirebaseAuth.Auth.auth().currentUser
Task {
do {
try await Auth.auth().revokeToken(withAuthorizationCode: authCodeString)
print("Good")
} catch {
print("Error")
}
do {
try await user?.delete()
print("Good Delete")
} catch {
print("Error")
}
}
}
英文:
I am implementing the Apple Login function using Firebase.
(https://firebase.google.com/docs/auth/ios/apple?hl=ko#configure_sign_in_with_apple)
The membership registration has been completed and displayed properly on the console.
The problem is the deletion of members.
Task {
do {
try await Auth.auth().revokeToken(withAuthorizationCode: authCodeString)
try await user?.delete()
self.updateUI()
} catch {
self.displayError(error)
}
}
There was an error using this code.
Task {
do {
try await Auth.auth().revokeToken(withAuthorizationCode: authCodeString)
print("Good")
} catch {
print("Error")
}
do {
try await user?.delete()
print("Good Delete")
} catch {
print("Error")
}
}
I modified 'auth.auth().revokeToken' and 'user?'delete()' to run in two steps as above code.
The error occurred in 'auth.auth().revokeToken'. However, Delete was successful and the test account was deleted from the Firebase console.
-
May I know why 'auth.auth().revokeToken' doesn't work?
-
Is there no problem if I don't do 'auth.auth().revokeToken'?
-
How can I print an 'revokeToken' error?
Below is my code.
private func deleteCurrentUser() {
do {
let nonce = try self.randomNonceString()
self.currentNonce = nonce
let appleIDProvider = ASAuthorizationAppleIDProvider()
let request = appleIDProvider.createRequest()
request.requestedScopes = [.fullName, .email]
request.nonce = self.sha256(nonce)
let authorizationController = ASAuthorizationController(authorizationRequests: [request])
authorizationController.delegate = self
authorizationController.presentationContextProvider = self
authorizationController.performRequests()
} catch {
// In the unlikely case that nonce generation fails, show error view.
print("실패")
}
}
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()
return hashString
}
private 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
}
func authorizationController(controller: ASAuthorizationController,
didCompleteWithAuthorization authorization: ASAuthorization) {
guard let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential else {
print("Unable to retrieve AppleIDCredential")
return
}
guard let _ = self.currentNonce else {
fatalError("Invalid state: A login callback was received, but no login request was sent.")
}
guard let appleAuthCode = appleIDCredential.authorizationCode else {
print("Unable to fetch authorization code")
return
}
guard let authCodeString = String(data: appleAuthCode, encoding: .utf8) else {
print("Unable to serialize auth code string from data: \(appleAuthCode.debugDescription)")
return
}
let user = FirebaseAuth.Auth.auth().currentUser
Task {
do {
try await Auth.auth().revokeToken(withAuthorizationCode: authCodeString)
print("Good")
} catch {
print("Error")
}
do {
try await user?.delete()
print("Good Delete")
} catch {
print("Error")
}
}
}
The code is not much different from what Google told you.
答案1
得分: 1
I would reconfigure to something like this
let task = Task {
do {
try await Auth.auth().revokeToken(withAuthorizationCode: authCodeString)
print("Good")
try await user?.delete()
print("Good Delete")
} catch {
print("Error \(error)")
}
}
Putting your delete code below the catch
is basically saying delete no matter what.
By putting it in the do
below the try
, the code to delete will be skipped if the call fails.
Also, notice that I added error
to the print
, that will print the actual error instead of just a generic message.
Also, make sure you hold on to the task at class
or struct
level, that way you can tell when the operation is actually done.
英文:
I would reconfigure to something like this
let task = Task {
do {
try await Auth.auth().revokeToken(withAuthorizationCode: authCodeString)
print("Good")
try await user?.delete()
print("Good Delete")
} catch {
print("Error \(error)")
}
}
Putting your delete code below the catch
is basically saying delete no matter what.
By putting it in the do
below the try
the code to delete will be skipped if the call fails.
Also, notice that I added error
to the print
, that will print the actual error instead of just a generic message.
Also, make sure you hold on to the task at class
or struct
level, that way you can tell when the operations is actually done.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论