Post

Replies

Boosts

Views

Activity

Reply to Migrating Sign in with Apple users for an app transfer
As a supplement, this is the complete code example for obtaining the token. Confidential information has been hidden. import requests import jwt from datetime import datetime, timedelta, timezone from cryptography.hazmat.primitives import serialization # 其他配置示例(注释掉的备用配置) KEY_ID = "Z7S8S2xxxx" TEAM_ID = "6VNZUKxxxx" CLIENT_ID = "com.game.friends.ios.toptop.xxxx" P8_KEY_FILE = "AuthKey_Z7S8S2xxxx.p8" def generate_client_secret(): """使用p8密钥生成JWT格式的client_secret""" try: # 从文件读取 p8 密钥内容 # with open(P8_KEY_FILE, 'r') as f: # p8_key_content = f.read() p8_key_content = serialization.load_pem_private_key( open(P8_KEY_FILE, 'rb').read(), password=None ) print(f"从文件读取密钥: {p8_key_content}") # 计算时间戳 now = datetime.now(timezone.utc) # 替代弃用的 utcnow() issued_at = int(now.timestamp()) expiration = int((now + timedelta(days=180)).timestamp()) # 创建JWT头部 headers = { "alg": "ES256", "kid": KEY_ID, } # 创建JWT有效载荷 payload = { "iss": TEAM_ID, "iat": issued_at, "exp": expiration, "aud": "https://appleid.apple.com", "sub": CLIENT_ID } print("生成的 payload:", payload) # 生成签名的JWT作为client_secret client_secret = jwt.encode( payload, p8_key_content, algorithm="ES256", headers=headers ) return client_secret except FileNotFoundError: print(f"密钥文件未找到: {P8_KEY_FILE}") return None except Exception as e: print(f"生成client_secret失败: {str(e)}") return None def get_apple_token(): """获取Apple的访问令牌""" # 生成JWT格式的client_secret client_secret = generate_client_secret() print("生成的 client_secret:", client_secret) if not client_secret: print("无法生成client_secret,退出") return None # 设置请求参数 url = "https://appleid.apple.com/auth/token" headers = {"Content-Type": "application/x-www-form-urlencoded"} data = { "grant_type": "client_credentials", "scope": "user.migration", "client_id": CLIENT_ID, "client_secret": client_secret, "redirect_uri": "https://example.com/auth/callback" } try: # 发送请求 response = requests.post(url, headers=headers, data=data) response.raise_for_status() # 检查HTTP错误 # 返回JSON响应 return response.json() except requests.exceptions.HTTPError as err: # 处理HTTP错误 print(f"HTTP错误 ({err.response.status_code}):") if err.response.text: print(err.response.text) return None except Exception as e: # 处理其他错误 print(f"请求失败: {str(e)}") return None # 主程序入口 if __name__ == "__main__": # 获取访问令牌 token_response = get_apple_token() if token_response: print("\n成功获取Apple访问令牌:") print(f"访问令牌: {token_response.get('access_token')}") print(f"令牌类型: {token_response.get('token_type')}") print(f"有效期: {token_response.get('expires_in')}秒") else: print("\n无法获取访问令牌,请检查错误信息")
Jun ’25
Reply to Migrating Sign in with Apple users for an app transfer
import jwt from datetime import datetime, timedelta, timezone from cryptography.hazmat.primitives import serialization # 其他配置示例(注释掉的备用配置) KEY_ID = "Z7S8S2xxxx" TEAM_ID = "6VNZUKxxxx" CLIENT_ID = "com.game.friends.ios.toptop.xxxx" P8_KEY_FILE = "AuthKey_Z7S8S2xxxx.p8" def generate_client_secret(): """使用p8密钥生成JWT格式的client_secret""" try: # 从文件读取 p8 密钥内容 # with open(P8_KEY_FILE, 'r') as f: # p8_key_content = f.read() p8_key_content = serialization.load_pem_private_key( open(P8_KEY_FILE, 'rb').read(), password=None ) print(f"从文件读取密钥: {p8_key_content}") # 计算时间戳 now = datetime.now(timezone.utc) # 替代弃用的 utcnow() issued_at = int(now.timestamp()) expiration = int((now + timedelta(days=180)).timestamp()) # 创建JWT头部 headers = { "alg": "ES256", "kid": KEY_ID, } # 创建JWT有效载荷 payload = { "iss": TEAM_ID, "iat": issued_at, "exp": expiration, "aud": "https://appleid.apple.com", "sub": CLIENT_ID } print("生成的 payload:", payload) # 生成签名的JWT作为client_secret client_secret = jwt.encode( payload, p8_key_content, algorithm="ES256", headers=headers ) return client_secret except FileNotFoundError: print(f"密钥文件未找到: {P8_KEY_FILE}") return None except Exception as e: print(f"生成client_secret失败: {str(e)}") return None def get_apple_token(): """获取Apple的访问令牌""" # 生成JWT格式的client_secret client_secret = generate_client_secret() print("生成的 client_secret:", client_secret) if not client_secret: print("无法生成client_secret,退出") return None # 设置请求参数 url = "https://appleid.apple.com/auth/token" headers = {"Content-Type": "application/x-www-form-urlencoded"} data = { "grant_type": "client_credentials", "scope": "user.migration", "client_id": CLIENT_ID, "client_secret": client_secret, "redirect_uri": "https://example.com/auth/callback" } try: # 发送请求 response = requests.post(url, headers=headers, data=data) response.raise_for_status() # 检查HTTP错误 # 返回JSON响应 return response.json() except requests.exceptions.HTTPError as err: # 处理HTTP错误 print(f"HTTP错误 ({err.response.status_code}):") if err.response.text: print(err.response.text) return None except Exception as e: # 处理其他错误 print(f"请求失败: {str(e)}") return None # 主程序入口 if __name__ == "__main__": # 获取访问令牌 token_response = get_apple_token() if token_response: print("\n成功获取Apple访问令牌:") print(f"访问令牌: {token_response.get('access_token')}") print(f"令牌类型: {token_response.get('token_type')}") print(f"有效期: {token_response.get('expires_in')}秒") else: print("\n无法获取访问令牌,请检查错误信息") ``` This is our code for obtaining the token. Confidential information has been hidden.
Jun ’25
Reply to Migrating Sign in with Apple users for an app transfer
The above issue has been resolved. After waiting for four days without taking any action, it fixed itself. On the Feedback Assistant, Apple replied after 11 days, stating that the issue had been resolved. It’s unclear whether Apple quietly fixed it in the background after receiving the feedback.
Replies
Boosts
Views
Activity
Jul ’25
Reply to Migrating Sign in with Apple users for an app transfer
FB18277746 (Urgent:Persistent 'invalid_client' error for over 72 hours during user migration for Sign in with Apple (App transfer completed on June 19, UTC+8))
Replies
Boosts
Views
Activity
Jun ’25
Reply to Migrating Sign in with Apple users for an app transfer
As a supplement, this is the complete code example for obtaining the token. Confidential information has been hidden. import requests import jwt from datetime import datetime, timedelta, timezone from cryptography.hazmat.primitives import serialization # 其他配置示例(注释掉的备用配置) KEY_ID = "Z7S8S2xxxx" TEAM_ID = "6VNZUKxxxx" CLIENT_ID = "com.game.friends.ios.toptop.xxxx" P8_KEY_FILE = "AuthKey_Z7S8S2xxxx.p8" def generate_client_secret(): """使用p8密钥生成JWT格式的client_secret""" try: # 从文件读取 p8 密钥内容 # with open(P8_KEY_FILE, 'r') as f: # p8_key_content = f.read() p8_key_content = serialization.load_pem_private_key( open(P8_KEY_FILE, 'rb').read(), password=None ) print(f"从文件读取密钥: {p8_key_content}") # 计算时间戳 now = datetime.now(timezone.utc) # 替代弃用的 utcnow() issued_at = int(now.timestamp()) expiration = int((now + timedelta(days=180)).timestamp()) # 创建JWT头部 headers = { "alg": "ES256", "kid": KEY_ID, } # 创建JWT有效载荷 payload = { "iss": TEAM_ID, "iat": issued_at, "exp": expiration, "aud": "https://appleid.apple.com", "sub": CLIENT_ID } print("生成的 payload:", payload) # 生成签名的JWT作为client_secret client_secret = jwt.encode( payload, p8_key_content, algorithm="ES256", headers=headers ) return client_secret except FileNotFoundError: print(f"密钥文件未找到: {P8_KEY_FILE}") return None except Exception as e: print(f"生成client_secret失败: {str(e)}") return None def get_apple_token(): """获取Apple的访问令牌""" # 生成JWT格式的client_secret client_secret = generate_client_secret() print("生成的 client_secret:", client_secret) if not client_secret: print("无法生成client_secret,退出") return None # 设置请求参数 url = "https://appleid.apple.com/auth/token" headers = {"Content-Type": "application/x-www-form-urlencoded"} data = { "grant_type": "client_credentials", "scope": "user.migration", "client_id": CLIENT_ID, "client_secret": client_secret, "redirect_uri": "https://example.com/auth/callback" } try: # 发送请求 response = requests.post(url, headers=headers, data=data) response.raise_for_status() # 检查HTTP错误 # 返回JSON响应 return response.json() except requests.exceptions.HTTPError as err: # 处理HTTP错误 print(f"HTTP错误 ({err.response.status_code}):") if err.response.text: print(err.response.text) return None except Exception as e: # 处理其他错误 print(f"请求失败: {str(e)}") return None # 主程序入口 if __name__ == "__main__": # 获取访问令牌 token_response = get_apple_token() if token_response: print("\n成功获取Apple访问令牌:") print(f"访问令牌: {token_response.get('access_token')}") print(f"令牌类型: {token_response.get('token_type')}") print(f"有效期: {token_response.get('expires_in')}秒") else: print("\n无法获取访问令牌,请检查错误信息")
Replies
Boosts
Views
Activity
Jun ’25
Reply to Migrating Sign in with Apple users for an app transfer
import jwt from datetime import datetime, timedelta, timezone from cryptography.hazmat.primitives import serialization # 其他配置示例(注释掉的备用配置) KEY_ID = "Z7S8S2xxxx" TEAM_ID = "6VNZUKxxxx" CLIENT_ID = "com.game.friends.ios.toptop.xxxx" P8_KEY_FILE = "AuthKey_Z7S8S2xxxx.p8" def generate_client_secret(): """使用p8密钥生成JWT格式的client_secret""" try: # 从文件读取 p8 密钥内容 # with open(P8_KEY_FILE, 'r') as f: # p8_key_content = f.read() p8_key_content = serialization.load_pem_private_key( open(P8_KEY_FILE, 'rb').read(), password=None ) print(f"从文件读取密钥: {p8_key_content}") # 计算时间戳 now = datetime.now(timezone.utc) # 替代弃用的 utcnow() issued_at = int(now.timestamp()) expiration = int((now + timedelta(days=180)).timestamp()) # 创建JWT头部 headers = { "alg": "ES256", "kid": KEY_ID, } # 创建JWT有效载荷 payload = { "iss": TEAM_ID, "iat": issued_at, "exp": expiration, "aud": "https://appleid.apple.com", "sub": CLIENT_ID } print("生成的 payload:", payload) # 生成签名的JWT作为client_secret client_secret = jwt.encode( payload, p8_key_content, algorithm="ES256", headers=headers ) return client_secret except FileNotFoundError: print(f"密钥文件未找到: {P8_KEY_FILE}") return None except Exception as e: print(f"生成client_secret失败: {str(e)}") return None def get_apple_token(): """获取Apple的访问令牌""" # 生成JWT格式的client_secret client_secret = generate_client_secret() print("生成的 client_secret:", client_secret) if not client_secret: print("无法生成client_secret,退出") return None # 设置请求参数 url = "https://appleid.apple.com/auth/token" headers = {"Content-Type": "application/x-www-form-urlencoded"} data = { "grant_type": "client_credentials", "scope": "user.migration", "client_id": CLIENT_ID, "client_secret": client_secret, "redirect_uri": "https://example.com/auth/callback" } try: # 发送请求 response = requests.post(url, headers=headers, data=data) response.raise_for_status() # 检查HTTP错误 # 返回JSON响应 return response.json() except requests.exceptions.HTTPError as err: # 处理HTTP错误 print(f"HTTP错误 ({err.response.status_code}):") if err.response.text: print(err.response.text) return None except Exception as e: # 处理其他错误 print(f"请求失败: {str(e)}") return None # 主程序入口 if __name__ == "__main__": # 获取访问令牌 token_response = get_apple_token() if token_response: print("\n成功获取Apple访问令牌:") print(f"访问令牌: {token_response.get('access_token')}") print(f"令牌类型: {token_response.get('token_type')}") print(f"有效期: {token_response.get('expires_in')}秒") else: print("\n无法获取访问令牌,请检查错误信息") ``` This is our code for obtaining the token. Confidential information has been hidden.
Replies
Boosts
Views
Activity
Jun ’25