DeviceCheck: Missing or badly formatted authorization token

I'm trying to implement a free trial mechanism using Apple's new DeviceCheck mechanism in iOS11. I've implemented the server part in RAILs 4. There's a fair bit of code, so I've put it in a gist: https://gist.github.com/jmfriend/b86f52f8f0649ad4cae176c08b77f000

I get the error: "Missing or badly formatted authorization token". That suggests that I'm doing something wrong when generating the JWT for the AuthKey_#####.p8 file.


For ease of reference, given it's probably where the issue is, this is the code that handles the p8 file:




def auth_header 
# The authentication key must must use the ES256 algorithm and be in the Base 64 URL–encoded JSON web token format. 
 "Bearer #{auth_token}"
 end

def auth_token 
 @auth_token ||= fetch_auth_token
end


def fetch_auth_token
   header = { typ: "JWT",
               alg: "ES256", 
               kid: key_id
 }
 body = { iss: team_id, 
          iat: DateTime.now().to_time.to_i , 
          exp: DateTime.now().to_time.to_i + 43_200 # 12hrs  }

 authentication_token = JWT.encode(body, auth_key, 'ES256', header_files = header) 
 authentication_token 
end 

def auth_key 
 file = File.read(developer_token_file) 
 key = OpenSSL::PKey::EC.new(file) 
 key.check_key 
 key 
end
Answered by jmf in 292355022

It looks like this issue is caused by using use an application identifier like this: xxxx.com.companyname.subdomain.* when using the dev version of your app. In the live version of your app, because this app id ends up being an explicit App ID, it will work.


I've tested this getting the dev version of my app to use the explicit App ID by using a different provisioning profile to normal.


Now, to figure out why getting 'Failed to find bit state'. My speculation is that you have to validate a device, before you can set its bits. Haven't seen this in the documentation, but that's my guess given the error.

Found one error in the above code: "header_files = header" should be "header_fields = header". This though does not solve the issue. Still get the same, "Missing or badly formatted authorization token".


If I try repeatedly using the device token to make it quicker to test different attempts to fix this, I get "Missing or incorrectly formatted device token payload". I assume this is because the device token has timed out. It would be handy if that timeout on dev was a lot longer as it makes it an even lengthy process trying to debug this.


My concern is that the code is fine, but it's something to do with my set-up. I've been doing App Store development for nine years, so my set-up is quite old in some ways.


Read elsewhere that the error ' "Missing or badly formatted authorization token" can also mean that the app requesting a DeviceCheck device token doesn't have an explicit App ID defined in your developer account.'


For my project, the profiles and entitlements that I've always used to publish apps use an application identifier like this: xxxx.com.companyname.subdomain.*


Is this likely to cause an issue resulting in "Missing or badly formatted authorization token"

Have now tried this against the live Apple server, and get a different response. Oddly, no longer get "Missing or badly formatted authorization token". However, I am getting a 200 response with the message: 'Failed to find bit state'. This is not JSON so broke my code that was expecting JSON. Does anyone know what this message means? It's in the official documentation, but no explanation that I can see of why you'd get it.

Accepted Answer

It looks like this issue is caused by using use an application identifier like this: xxxx.com.companyname.subdomain.* when using the dev version of your app. In the live version of your app, because this app id ends up being an explicit App ID, it will work.


I've tested this getting the dev version of my app to use the explicit App ID by using a different provisioning profile to normal.


Now, to figure out why getting 'Failed to find bit state'. My speculation is that you have to validate a device, before you can set its bits. Haven't seen this in the documentation, but that's my guess given the error.

Turns out that 'Failed to find bit state' simply means what it says, so far nothing has been set for the bits for this device for this developer. I'd expected to get a JSON response indicating this, but you don't, you get this text. If you're not expecting it, but just JSON, your JSON parsing will obviously choke. So, you have to write your code, expecting that you may get back either JSON, or something that is simply text.

Hi,


We are having a very similar issue with DeviceCheck. Did you ever get it to work?


many thanks,

Rob

DeviceCheck: Missing or badly formatted authorization token
 
 
Q