You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DeviceCheck调用异常:Apple服务器返回401无法验证授权令牌

Troubleshooting Apple DeviceCheck 401 "Unable to verify authorization token" Error

I'm trying to implement Apple's DeviceCheck feature, but keep getting a 401 Unable to verify authorization token response from Apple's servers. The device_token is sent as a Base64-encoded string in the JSON payload to my Python server. Here's my code example:

def device_check_query(device_token):
    data = {
        'device_token': device_token,
        'transaction_id': str(uuid4()),
        'timestamp': int(time.time() * 1000),
    }
    jw_token = get_jw_token()
    headers = {'Authorization': 'Bearer ' + jw_token}
    response = requests.post(QUERY_URL, json=data, headers=headers)
    return response.content

def get_jw_token():
    with open(KEY_FILE, 'r') as cert_file:
        certificate = cert_file.read()
    jw_token = jwt.encode(
        {'iss': TEAM_ID},
        certificate,
        algorithm='ES256',
        headers={'kid': KEY_ID})
    return jw_token

Let's walk through the most likely causes for this 401 error and how to fix them:

1. Incorrect Private Key Handling

Your current code reads the .p8 key as a raw text string, but ES256 requires the private key to be parsed properly. Apple's DeviceCheck private keys are in PEM format, and loading them as plain text can lead to invalid signatures. Try using the cryptography library to load the key correctly:

from cryptography.hazmat.primitives import serialization

def get_jw_token():
    with open(KEY_FILE, 'rb') as cert_file:
        private_key = serialization.load_pem_private_key(
            cert_file.read(),
            password=None,
        )
    jw_token = jwt.encode(
        {'iss': TEAM_ID},
        private_key,
        algorithm='ES256',
        headers={'kid': KEY_ID})
    return jw_token

Also double-check that your key file includes the full -----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY----- headers with no extra whitespace or line breaks.

2. Mismatched kid or iss Values

These two values are critical for Apple to verify your JWT:

  • KEY_ID must be the exact 10-character identifier associated with your DeviceCheck private key (found in the Apple Developer Portal next to the key)
  • TEAM_ID is your 10-character Apple Developer Team ID, not your app's bundle ID or any other identifier
    Even a single typo or extra space here will trigger a 401 error.

3. JWT Payload/Header Validation

Apple expects a minimal, correctly formatted JWT:

  • The payload should only contain the iss claim set to your Team ID (your current code does this, but avoid adding extra claims accidentally)
  • The header must include the kid (key ID) and alg (set to ES256) fields
    You can debug your generated JWT by decoding it without verifying the signature:
import jwt
decoded = jwt.decode(jw_token, options={"verify_signature": False})
print(decoded)  # Check payload
print(jwt.get_unverified_header(jw_token))  # Check header

Make sure the output matches exactly what Apple requires.

4. Invalid Device Token Format

Even if you're sending a Base64 string, confirm:

  • It's the raw device token received from iOS, encoded with standard Base64 (not URL-safe Base64)
  • There are no extra characters like newlines, spaces, or hex encoding in the string
  • You haven't accidentally truncated or modified the token before sending it

5. Server Clock Sync Issues

Apple's servers strictly validate the JWT's implicit timestamp. If your server's clock is off by more than a few minutes, the token will be considered expired or not yet valid. Ensure your server has NTP enabled to keep time synchronized accurately.

6. Wrong API Endpoint

Make sure QUERY_URL matches your app's environment:

  • Production: https://api.devicecheck.apple.com/v1/query_two_bits
  • Sandbox: https://api.development.devicecheck.apple.com/v1/query_two_bits
    Using the wrong endpoint for your build will also result in a 401 error.

内容的提问来源于stack exchange,提问作者Lukas Dambrauskas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:21:04