NEW: My new book Pro SwiftUI is out now – level up your SwiftUI skills today! >>

How to figure out the Sign In With Apple Token Revocation requirements after June 30th?

Forums > iOS

Hey everyone!

I have been investigating the upcoming June 30th requirements from Apple regarding apps that offer account creation with Apple Auth (they now require deletion, and part of that requirement is revoking tokens). Revoking tokens, to my knowledge, removes the Apple ID association to the app. So when you go back to the app and create a new account, you will actually be prompted as though you are a brand new user again (instead of using your old associated Apple ID credentials which were bound to the app in your settings).

I am not very confident in my solution, I have an attempted solution, but the status code always returns 200 no matter what my input is. I havn't been able to test this thoroughly and am hoping to get some feedback or critique on my approach.

I have posted the question here, as well:

The update from Apple:

The following functions live in the same class (ViewModel). The first does my login/registration flow. Some of it is a bit custom, but you can see I grab the token string and nonce for client_secret. The second function resembles the POST request for token revocation (which gets called from a delete account function not shown). I did not include my delete account function as it doesn't add value to the problem. The first function is used to assign the two values to app storage, and the second function would be called from my delete account method to perform the POST request.

public func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
    // Sign in using Firebase Auth
    if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential {
        guard let nonce = currentNonce else {
            print("Invalid state: A login callback was received, but no login request was sent.")

        // JWT
        guard let appleIDToken = appleIDCredential.identityToken else {
            print("Unable to fetch identity token")

        guard let idTokenString = String(data: appleIDToken, encoding: .utf8) else {
            print("Unable to serialize token string from data")

        let credential = OAuthProvider.credential(withProviderID: "", idToken: idTokenString, rawNonce: nonce)
        Auth.auth().signIn(with: credential) { result, error in
            if error != nil {
            else { // successful auth, we can now check if its a login or a registration
                guard let user = Auth.auth().currentUser else {
                    print("No user was found.")
                let db = Firestore.firestore()
                let docRef = db.collection("Users").document(("\(user.uid)"))
                docRef.getDocument{ (document, error) in
                    if let document = document, document.exists {
                        // User is just logging in, their db store exists
                        print("Successful Apple login.")

                        // Token revocation requirements
                        self.clientSecret = nonce
                        self.appleToken = idTokenString

                        if (self.isDeletingAccount == true) {
                            print("Is deleting account.")
                            self.isReauthenticated = true
                        self.isLogged = true
                    else { // document does not exist! we are registering a new user
                            "name": "\(appleIDCredential.fullName?.givenName ?? "")"
                        print("Successful Apple registration.")

                        self.clientSecret = nonce
                        self.appleToken = idTokenString

                        self.isLogged = true

// POST request to revoke user's Apple token from Barfix app
func appleAuthTokenRevoke(completion: (([String: Any]?, Error?) -> Void)? = nil) {

    let paramString: [String : Any] = [
        "client_id": Bundle.main.bundleIdentifier!, //"com.MyCompany.Name",
        "client_secret": self.clientSecret,
        "token": self.appleToken,
        "token_type_hint": "access_token"

    let url = URL(string: "")!

    var request = URLRequest(url: url)
    request.httpMethod = "POST"

    do {
        request.httpBody = try paramString, options: .prettyPrinted)
    catch let error {
        completion?(nil, error)

    request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")

    let task =  URLSession.shared.dataTask(with: request as URLRequest)  { (data, response, error) in
        guard let response = response as? HTTPURLResponse, error == nil else {
            print("error", error ?? URLError(.badServerResponse))

        guard (200 ... 299) ~= response.statusCode else {
            print("statusCode should be 2xx, but is \(response.statusCode)")
            print("response = \(response)")

        if let error = error {
        else {
            print("deleted accont")


Hi! have you make this deletion thing works?? i´m on the same situation, completely newby with swiftui and need to deliver an app with this feature running to publish in the appStore



Apologies for late reply.

The following solution assumes you are able to run some server-side code. In this case, it is with the Firebase functions feature which containerizes the JS module displayed in this github readme.

This is the template I followed to successfully implement everything.


Hacking with Swift is sponsored by Judo

SPONSORED Let’s face it, SwiftUI previews are limited, slow, and painful. Judo takes a different approach to building visually—think Interface Builder for SwiftUI. Build your interface in a completely visual canvas, then drag and drop into your Xcode project and wire up button clicks to custom code. Download the Mac App and start your free trial today!

Try now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

Unknown user

You are not logged in

Log in or create account

Link copied to your pasteboard.