ios – Auth0’s JWT not working with Apple’s REST API


I am making an attempt to get an entry code by way of Apple’s REST API.

To take action, I am following the directions at entitled “Generate and validate tokens.”

Making a JWT is a requirement. Primarily based on the directions, I create the next JWT header:

     "alg": "ES256",
     "child": "<child>"

Above, “child” is my non-public 10-character key identifier I get from App Retailer Join following Apple’s directions. Some folks have talked about that the JWT header should additionally embody “typ”: “JWT”. So, I’ve additionally used a model of the header that does.

Subsequent, I create the next JWT payload:

     "iss": "<iss>",
     "iat": <UNIX epoch time>,
     "exp": <UNIX epoch time>,
     "aud": "",
     "sub": "<client_id>"

Above, “iss” is my 10-character Staff ID related to my developer account as instructed by Apple. In a distinct set of directions, Apple mentions that “iss” ought to be my issuer ID from the API Keys web page in App Retailer Join. So, I’ve additionally used a model of the payload that makes use of this different model of “iss.”

“client_id” is my App ID. In keeping with some folks, my App ID is my app’s Bundle Identifier. In keeping with others, it is the quantity that seems on the very finish of the url that hyperlinks to my app within the App Retailer. So, I’ve used a model of the payload that makes use of this quantity and likewise one which makes use of the Bundle Identifier. I’ve additionally used a model of the payload that does not embody the “sub” parameter as a result of in a distinct set of directions by Apple, it isn’t included.

I’ve used an “exp” that expires 10min sooner or later. In keeping with some folks, “iat” ought to be set to a couple seconds or minutes in the past. I’ve taken this into consideration.

Primarily based on all of the above data, I’ve tried utilizing 2 completely different JWT headers and eight completely different JWT payloads. Subsequently, I’ve used 16 completely different JWT tokens.

To creat and signal my JWT token, Apple hyperlinks to Auth0’s web site There, I begin by deciding on the ES256 algorithm within the debugger as a result of based on the JWT header, “alg” is “ES256”.

I then paste my JWT header into the HEADER part of the debugger and my payload into the PAYLOAD part.

The non-public key I downloaded from App Retailer Join is in .p8 format. To ensure that it to work with Auth0’s debugger, I convert it to PKCS #8 format as follows:

First, I convert it to .pem format:

 openssl pkcs8 -in AuthKey_<child>.p8 -nocrypt -out Auth0_<child>.pem

I then convert the .pem to PKCS #8 format:

 openssl pkcs8 -topk8 -inform PEM -in Auth0_<child>.pem 
     -nocrypt > Auth0_priv_pkcs8

Lastly, I generate a public key that corresponds with Auth0_priv_pkcs8:

 openssl ec -in Auth0_priv_pkcs8 -pubout > Auth0_pub_pkcs8

In Auth0’s debugger, I paste Auth0_pub_pkcs8 within the public key part and Auth0_priv_pkcs8 within the non-public key part.

Auth0 states, “Signature Verified.” So, I instantly copy my signed JWT and paste it within the following iOS func, assigning it to client_secret:

 func get_accessToken(code: String) {
     let client_id = "<JWT payload's sub worth>",
         client_secret = "<JWT signed utilizing Auth0's web site>",
         url = URL(string: "")!
     var urlRequest = URLRequest(url: url, cachePolicy: URLRequest.CachePolicy.reloadIgnoringLocalCacheData, timeoutInterval: 60.0)
     urlRequest.setValue("utility/x-www-form-urlencoded", forHTTPHeaderField: "Content material-Sort")
     urlRequest.httpMethod = "POST"
     let parameters: [String: Any] = [
         "client_id": client_id,
         "client_secret": client_secret,
         "code": code,//An authorization_code that has just been received. Example: cb45463c23057491faf97ac07f111a143.0.rryus.CX5XwXNQ04461uwcZhQStg
         "grant_type": "authorization_code"
     urlRequest.httpBody = parameters.percentEncoded()
     let session = URLSession.shared,
         activity = session.dataTask(with: urlRequest) { knowledge, response, error in
         guard let knowledge = knowledge,
               let response = response as? HTTPURLResponse,
                   error == nil else {
             // verify for elementary networking error
         do {
             let json = attempt JSONSerialization.jsonObject(with: knowledge, choices: .allowFragments)
         } catch {
             print(error)//error = "invalid_client"; on a regular basis
         guard (200 ... 299) ~= response.statusCode else {
             // verify for http errors

The above func executes as quickly as I get an authorization code from Apple’s API. After it executes, I all the time get error = “invalid_client”;

As talked about earlier, I’ve modified the JWT header and payload parameters a number of instances primarily based on numerous pointers and opinions. This has resulted into me having 16 completely different signed JWTs from Auth0’s web site they usually’ve all yielded error = “invalid_client”.

My workforce has a number of apps on the App Retailer. My understanding is that the non-public key I downloaded from App Retailer Join ought to work for all apps. However I am additionally questioning if maybe Apple’s API expects an App ID that belongs to one in every of my different apps and never the one I am at the moment engaged on. If that is the case, then may this be an Apple API bug? If not, then have I made an error anyplace or is there a problem with Auth0’s debugger?


Leave a Reply