当前位置: 首页 > article >正文

asa(苹果Apple Search Ads平台)授权调用接口

一、OAuth 认证

1. 认证流程

Implementing OAuth for the Apple Search Ads API

This implementation process guides you through the following steps:

  • Invite users with API permissions.
  • Generate a private-public key pair.
  • Extract a public key from your persisted private key.
  • Upload a public key.
  • Create a client secret.
  • Request an access token.
  1. 邀请拥有api权限的用户
  2. 生成专用公钥对
  3. 从持久化私钥中提取公钥
  4. 上传公钥
  5. 创建客户端密钥
  6. 请求访问令牌

2. 邀请用户

Invite Users

Account administrators invite users with API permissions using the following process:

  • From the Apple Search Ads UI, choose Sign In > Advanced and log in as an account administrator.
  • From the Users menu in the top-right corner, select the account to invite users to.
  • Choose Account Settings > User Management.
  • Click Invite Users to invite users to your Apple Search Ads organization.
  • In the User Details section, enter the user’s first name, last name, and Apple ID.
  • In the User Access and Role section, select an API user role. For non-API roles, see Invite users to your account.
  • Click Send Invite. The invited user receives an email with a secure code. The user signs into the secure Apple URL in the email and inputs the provided code, which activates the user’s account.

管理员账号通过以下过程邀请用户具有api权限:

  1. 从Apple Search Ads UI中,选择“登录”>“高级(Advanced)”,然后以帐户管理员身份登录

登陆网址

图2-1:登陆界面

  1. 从右上角的“用户”菜单中,选择要邀请用户加入的帐户。
  1. 选择“帐户设置”>“用户管理”。
  2. 单击邀请用户以邀请用户加入您的Apple Search Ads组织。
  3. 在“用户详细信息”部分,输入用户的名字、姓氏和Apple ID。
  4. 在“用户访问权限和角色”部分中,选择一个API用户角色(Read Only、API Read Only)。有关非API角色,请参阅邀请用户加入您的帐户。
  5. 单击发送邀请。受邀用户收到一封带有激活码的电子邮件。用户登录电子邮件中的安全Apple URL并输入提供的激活码,从而激活用户的帐户:

整个过程开发者需要提供 Apple ID,具有苹果广告账户管理员权限的账号授权对应子账户的【最低 API 只读】权限;用户前往授权 Apple ID 邮箱查收邀请邮件发送对应的【激活码】,点击接受邀请,此时跳转至苹果广告登录后台,输入邀请【激活码】,完成苹果广告后台登录流程;

图2-2:Apple ID 邮箱查收邀请邮件并跳转激活账号

3. 密钥管理

需要下载openssl

  1. openssl生成私钥文件:openssl ecparam -genkey -name prime256v1 -noout -out private-key.pem

Parameter

Description

-name

prime256v1 — the Elliptic Curve Digital Signature Algorithm (ECDSA) filename.

prime256v1:椭圆曲线数字签名算法(ECDSA),key算法对应EC

-out

The .pem filename where you generate and store the key pair.

文件名

  1. openssl通过私钥文件抽取公钥文件:openssl ec -in private-key.pem -pubout -out public-key.pem

Parameter

Description

-in

The private key filename: private-key.pem

输入文件名

-out

The ec256-public-key file where you generate and store the public key.

输出文件名

  1. openssl通过私钥文件生成 pkcs8 编码文件: openssl pkcs8 -topk8 -nocrypt -in private-key.pem -out pkcs8_rsa_private_key.pem
  2. 将公钥粘贴到 ASA 后台(设置 > API),生成 clientId, teamId, keyId

图3-1:通过公钥生成clientId,teamId,keyId

4. 代码生成服务端token

将asa后台生成的 clientId, teamId, keyId以及私钥生成的 pkcs8 编码字符串拿出来备用

  1. java代码

依赖

<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.10.3</version>
</dependency>

代码

public static void main(String[] args) throws Exception {
    // 需要保存的密钥信息
    String pkcs8PrivateKey = "MIxxxxxx";
    String keyId = "8xxx8";
    String teamId = "Sxxxb";
    String clientId = "Sxxxb";
    String audience = "https://appleid.apple.com";
    String alg = "ES256";
    // 获取私钥key
    byte[] decodeBase64Key = Base64.decodeBase64(pkcs8PrivateKey);
    // ec Keys for the Elliptic Curve algorithm. 椭圆螺线加密算法
    KeyFactory keyFactory = KeyFactory.getInstance("EC");
    PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodeBase64Key);
    PrivateKey privateKey = keyFactory.generatePrivate(keySpec);

    // 构建载荷
    
    Map<String, Object> headers = new HashMap<>();
    headers.put("alg", alg);
    headers.put("kid", keyId);
    long iat = DateUtil.currentSeconds();
    long exp = iat + 86400 * 180;
    Map<String, Object> payload = new HashMap<>();
    payload.put("sub", clientId);
    payload.put("aud", audience);
    payload.put("iat", iat);
    payload.put("exp", exp);
    payload.put("iss", teamId);

    // 生成token
    String jwtToken = Jwts.builder().setClaims(payload).setHeaderParams(headers).signWith(SignatureAlgorithm.ES256, privateKey).compact();
}
  1. python代码
import os
import datetime as dt
from authlib.jose import jwt
from Crypto.PublicKey import ECC

private_key_file = "private-key.pem"
public_key_file = "public-key.pem"
client_id = "SEARCHADS.9703f56c-10ce-4876-8f59-e78e5e23a152"
team_id = "SEARCHADS.9703f56c-10ce-4876-8f59-e78e5e23a152"
key_id = "d136aa66-0c3b-4bd4-9892-c20e8db024ab"
audience = "https://appleid.apple.com"
alg = "ES256"

# Create the private key if it doesn't already exist.
if os.path.isfile(private_key_file):
    with open(private_key_file, "rt") as file:
        private_key = ECC.import_key(file.read())
else:
    private_key = ECC.generate(curve='P-256')
    with open(private_key_file, 'wt') as file:
        file.write(private_key.export_key(format='PEM'))

# Extract and save the public key.
public_key = private_key.public_key()
if not os.path.isfile(public_key_file):
    with open(public_key_file, 'wt') as file:
        file.write(public_key.export_key(format='PEM'))

# Define the issue timestamp.
issued_at_timestamp = int(dt.datetime.utcnow().timestamp())
# Define the expiration timestamp, which may not exceed 180 days from the issue timestamp.
expiration_timestamp = issued_at_timestamp + 86400*180

# Define the JWT headers.
headers = dict()
headers['alg'] = alg
headers['kid'] = key_id

# Define the JWT payload.
payload = dict()
payload['sub'] = client_id
payload['aud'] = audience
payload['iat'] = issued_at_timestamp
payload['exp'] = expiration_timestamp
payload['iss'] = team_id

# Open the private key.
with open(private_key_file, 'rt') as file:
    private_key = ECC.import_key(file.read())

# Encode the JWT and sign it with the private key.
client_secret = jwt.encode(
    header=headers,
    payload=payload,
    key=private_key.export_key(format='PEM')
).decode('UTF-8')

# Save the client secret to a file.
with open('client_secret.txt', 'w') as output:
     output.write(client_secret)

载荷示例

// Header
{
"alg": "ES256",
"kid": "d136aa66-0c3b-4bd4-9892-c20e8db024ab"
}
// Payload
{
"iss": "SEARCHADS.9703f56c-10ce-4876-8f59-e78e5e23a152",
"iat": 2234567891,
"exp": 2234567900,
"aud": "https://appleid.apple.com",
"sub": "SEARCHADS.9703f56c-10ce-4876-8f59-e78e5e23a152"
}

5. 请求获取accesstoken

curl -X POST \
-H 'Host: appleid.apple.com' \
-H 'Content-Type: application/x-www-form-urlencoded' \
'https://appleid.apple.com/auth/oauth2/token?grant_type=client_credentials&
client_id=SEARCHADS.27478e71-3bb0-4588-998c-182e2b405577&client_secret=eyJ0
eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.zI1NiIsImprdSI6Imh0dHBzOi8vYXV0aC5kZXYuYXB
pLnJpY29oL3YxL2Rpc2NvdmVyeS9rZXlzIiwia2lkIjoiMmIyZTgyMTA2NzkxZGM4ZmFkNzgxNW
Q3ZmI1NDRhNjJmNzJjMTZmYSJ9.eyJpc3MiOiJodHRwczovL2F1dGguZGV2LmFwaS5yaWNvaC8iL
CJhdWQiOiJodHRwczovL2lwcy5kZXYuYXBpLnJpY29oLyIsImlhdCI6MTQ5MDg1Mjc0MSwiZXhwI
joxNDkwODU2MzQxLCJjbGllbnRfaWQiOiI4ODQwMWU1MS05MzliLTQ3NzktYjdmNy03YzlmNGIzZj
kyYzAiLCJzY29wZSI6Imh0dHBzOi8vaXBzLmRldi5hcGkucmljb2gvdjEiLCJyaWNvaF9tc3Mi
OnsibWVkaWEiOnsicXVvdGEiOjEwLCJ0aHJvdHRsZSI6eyJ2YWx1ZSI6MCwid2luZG93IjowfX1
9fQ.jVq_c_cTzgsLipkJKBjAHzm8KDehW4rFA1Yg0EQRmqWmBDlEKtpRpDHZeF6ZSQfNH2OlrBW
FBiVDV9Th091QFEYrZETZ1IE1koAO14oj4kf8TCmhiG_CtJagvctvloW1wAdgMB1_Eubz9a8oim
cODqL7_uTmA5jKFx3ez9uoqQrEKZ51g665jSI6NlyeLtj4LrxpI9jZ4zTx1yqqjQx0doYQjBPhOB
06Z5bdiVyhJDRpE8ksRCC3kDPS2nsvDAal28sMgyeP8sPvfKvp5sa2UsH78WJmTzeZWcJfX2C2ba3
xwRMB5LaaVrQZlhj9xjum0MfDpIS1hJI6p5CHZ8w&scope=searchadsorg'

Request header

Description

Host

Required. appleid.apple.com

Content-Type

Required. application/x-www-form-urlencoded

Request parameter

Type

Description

client_id

String

Required. You receive your clientId when you upload a public key.

client_secret

String

Required. The client secret is a JWT that you create and sign with your private key.

grant_type

String

Required. The method to request authorization and get an access token.

The value is client_credentials.

scope

String

Required. Defines the access permissions you request from the user, and limits the authorization of the access token you receive.

The value is searchadsorg.

返回值:

{
"access_token":"eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIiwia2lkIjpudWxsfQ
..lXm332TFi0u2E9YZ.bVVBvsjcavoQbBnQVeDiqEzmUIlaH9zLKY6rl36A_TD8wvgvWxp
yBXMQuhs-qWG_dxQ5nfuJEIxOp8bIndfLE_4a3AiYtW0BsppO3vkWxMe0HWnzglkFbKUHU
3PaJbLHpimmnLvQr44wUAeNcv1LmUPaSWT4pfaBzv3dMe3PNHJJCLVLfzNlWTmPxViIivQ
t3xyiQ9laBO6qIQiKs9zX7KE3holGpJ-Wvo39U6ZmGs7uK9BoNBPaFtd_q914mb9ChHAKc
QaxF3Gadtu_Z5rYFg.vD0iQuRwHGYVnDy27qexCw",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "searchadsorg"
}

6. 调用接口携带accesstoken和orgId

  1. 获取 orgid:

(1)通过 Apple 页面拿到 orgId;


 

(2)通过 API 的方式拿到 orgId;

curl "https://api.searchads.apple.com/api/v3/acls

" \-H "Authorization: Bearer {access_token}" \

  1. 通过accesstoken和orgId访问所有接口
curl "https://api.searchads.apple.com/api/v4/campaigns" \
-H "Authorization: Bearer {access_token}" \
-H "X-AP-Context: orgId={orgId}"

http://www.kler.cn/a/7866.html

相关文章:

  • nacos配置中心入门
  • 如何保证Redis与MySQL双写一致性
  • vue3+elementplus+虚拟树el-tree-v2+多条件筛选过滤filter-method
  • React 中如何解析字符串中的 html 结构
  • Ps:OpenColorIO 设置
  • mysql 配置文件 my.cnf 增加 lower_case_table_names = 1 服务启动不了的原因
  • 【设置应用程序图标-启动图片 Objective-C语言】
  • Vue:初识Vue
  • 数字化可视化大屏:创新与融合的未来
  • 02.数据结构之算法
  • 指针的详细运用介绍(高阶)
  • NIFI大数据进阶_Kafka使用相关说明_实际操作Kafka消费者处理器_来消费kafka数据---大数据之Nifi工作笔记0037
  • Vue3通透教程【九】父子组件通讯一目了然
  • 【从零开始学习 UVM】12.8、UVM RAL(续更) —— UVM RAL Model 实战项目(基于AXI总线的寄存器读写实例)
  • 从前M个字母中取N个的无重复排列 [2*+]
  • SQL VQ13 统计每天总刷题数
  • 基于价值认同的需求侧电能共享分布式交易策略(Matlab代码实现)
  • 大数据=SQL Boy,SQL Debug打破SQL Boy 的僵局
  • HTTP1.1、HTTP2和HTTP3是HTTP协议的三个版本——相同点和不同点
  • LinkedIn领英一、二、三度人脉分别代表什么意思?如何突破人脉限制开启领英社交化客户开发
  • 开心档之C++ 运算符
  • 【机器学习学习笔记】机器学习入门监督学习
  • Linux系统常用命令大全
  • 泡泡玛特“失速”,盲盒经济迎来拐点?
  • MySQL 查询常用操作(2) —— 条件查询 where
  • chatGPT的API一次多少钱-怎么用chatGPT解决问题