Issue with Generating access token with Apple Sign for revoking it after.

I am trying to generate access token accroding to https://developer.apple.com/documentation/sign_in_with_apple/generate_and_validate_tokens for apple sign in and revoke it after. However always getting "{"error":"invalid_client"}" what I am doing wrong?


` func validateTokens(completion: (([String: Any]?, Error?) -> Void)? = nil) {
    guard let code = keychain["code"],
      let userId = Bundle.main.bundleIdentifier
    else {
      log("Failed getting token")
      return
    }

    let paramString: [String: Any]

    do {
      let key = try privateKey()
      let token = try jwtSignedToken(ecSECp256rPrivateKey: key)
      paramString = [
        "client_id": userId, //"com.MyCompany.Name",
        "client_secret": token,
        "grant_type": "authorization_code",
      ]
    } catch {
      return
    }
    let url = URL(string: "https://appleid.apple.com/auth/token")!

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

    do {
      request.httpBody = try JSONSerialization.data(withJSONObject: paramString, options: .prettyPrinted)
    } catch let error {
      log("Account apple delete %@", error.localizedDescription)
      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))
        return
      }

      guard (200...299) ~= response.statusCode else {
        log("statusCode should be 2xx, but is %@", "\(response.statusCode)")
        log("response = %@", "\(response)")
        return
      }
      if let error = error {
        log("%@", error.localizedDescription)
      } else {
        log("token just has generated")
      }
    }
    task.resume()
  }
}

extension Data {

  init?(base64URLEncodedString: String) {
    let unpadded =
      base64URLEncodedString
      .replacingOccurrences(of: "-", with: "+")
      .replacingOccurrences(of: "_", with: "/")
    let padCount: Int
    switch unpadded.count % 4 {
    case 0: padCount = 0
    case 1: return nil
    case 2: padCount = 2
    case 3: padCount = 1
    default: fatalError()
    }
    self.init(base64Encoded: String(unpadded + String(repeating: "=", count: padCount)))
  }

  var base64URLEncodedString: String {
    let base64 = self.base64EncodedString()
    return String(base64.split(separator: "=").first!)
      .replacingOccurrences(of: "+", with: "-")
      .replacingOccurrences(of: "/", with: "_")
  }
}

func jwtHeader(kid: String) -> String {
  struct Header: Codable {
    var alg: String
    var kid: String 
  }
  let header = Header(alg: "ES256", kid: kid)
  return (try? JSONEncoder().encode(header).base64URLEncodedString) ?? ""
}

func jwtPayload(iss: String, exp: Date) -> String {
  // We round the expiry date up because it’s not clear how servers are going
  // to cope with fractional values.
  let exp = Date(timeIntervalSinceReferenceDate: exp.timeIntervalSinceReferenceDate.rounded(.up))
  struct Payload: Codable {
    var iss: String
    var exp: Date
    var iat: Int
    var aud: String
    var sub: String
  }
  let payload = Payload(iss: iss, exp: exp, iat: 1437179036, aud: "https://appleid.apple.com", sub: Keys.appBundleId)
  let encoder = JSONEncoder()
  encoder.dateEncodingStrategy = .secondsSince1970
  return (try? encoder.encode(payload).base64URLEncodedString) ?? ""
}

func jwtSignedToken(
  kid: String = "keyId", iss: String = "teamId", exp: Date = Date().addingTimeInterval(120),
  ecSECp256rKeyK keyK: Data
) throws -> String {
  let header = jwtHeader(kid: kid)
  let payload = jwtPayload(iss: iss, exp: exp)
  let signingInput = "\(header).\(payload)"
  let privateKey = try P256.Signing.PrivateKey(rawRepresentation: keyK)
  let sig = try privateKey.signature(for: Data(signingInput.utf8)).rawRepresentation
  return "\(signingInput).\(sig.base64URLEncodedString)"
}

func privateKey() throws -> SecKey {
  let privateKeyRawBytes = [UInt8]([
///generate like in https://developer.apple.com/forums/thread/681267
  ])

  var error: Unmanaged<CFError>?
  let privateSecKey = SecKeyCreateWithData(
    Data(privateKeyRawBytes) as CFData,
    [
      kSecAttrKeyType: kSecAttrKeyTypeECSECPrimeRandom,
      kSecAttrKeyClass: kSecAttrKeyClassPrivate,
    ] as NSDictionary, &error)
  return privateSecKey!
}

func jwtSignedToken(
  kid: String = "keyId", iss: String = teamId", exp: Date = Date().addingTimeInterval(120),
  ecSECp256rPrivateKey privateKey: SecKey
) throws -> String {
  var errorCF: Unmanaged<CFError>?
  guard let keyData = SecKeyCopyExternalRepresentation(privateKey, &errorCF) as Data? else {
    throw errorCF!.takeRetainedValue()
  }
  let keyK = keyData.suffix(0x20)
  return try jwtSignedToken(kid: kid, iss: iss, exp: exp, ecSECp256rKeyK: keyK)
}
Issue with Generating access token with Apple Sign for revoking it after.
 
 
Q