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

2023-10-22 00:10

本文主要是介绍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权限:

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

登陆网址

图2-1:登陆界面

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

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

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

3. 密钥管理

需要下载openssl

  • 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.

文件名

  • 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.

输出文件名

  • openssl通过私钥文件生成 pkcs8 编码文件: openssl pkcs8 -topk8 -nocrypt -in private-key.pem -out pkcs8_rsa_private_key.pem
  • 将公钥粘贴到 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";// 获取私钥keybyte[] 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);// 生成tokenString jwtToken = Jwts.builder().setClaims(payload).setHeaderParams(headers).signWith(SignatureAlgorithm.ES256, privateKey).compact();
}

2. python代码

import os
import datetime as dt
from authlib.jose import jwt
from Crypto.PublicKey import ECCprivate_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"
}

检查client_secret是否正确:JSON Web Tokens - jwt.io

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

  • 获取 orgid:

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


 

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

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

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

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

这篇关于asa(苹果Apple Search Ads平台)授权调用接口的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/257847

相关文章

SpringBoot实现不同接口指定上传文件大小的具体步骤

《SpringBoot实现不同接口指定上传文件大小的具体步骤》:本文主要介绍在SpringBoot中通过自定义注解、AOP拦截和配置文件实现不同接口上传文件大小限制的方法,强调需设置全局阈值远大于... 目录一  springboot实现不同接口指定文件大小1.1 思路说明1.2 工程启动说明二 具体实施2

Java调用Python脚本实现HelloWorld的示例详解

《Java调用Python脚本实现HelloWorld的示例详解》作为程序员,我们经常会遇到需要在Java项目中调用Python脚本的场景,下面我们来看看如何从基础到进阶,一步步实现Java与Pyth... 目录一、环境准备二、基础调用:使用 Runtime.exec()2.1 实现步骤2.2 代码解析三、

Python如何调用另一个类的方法和属性

《Python如何调用另一个类的方法和属性》在Python面向对象编程中,类与类之间的交互是非常常见的场景,本文将详细介绍在Python中一个类如何调用另一个类的方法和属性,大家可以根据需要进行选择... 目录一、前言二、基本调用方式通过实例化调用通过类继承调用三、高级调用方式通过组合方式调用通过类方法/静

C#控制台程序同步调用WebApi实现方式

《C#控制台程序同步调用WebApi实现方式》控制台程序作为Job时,需同步调用WebApi以确保获取返回结果后执行后续操作,否则会引发TaskCanceledException异常,同步处理可避免异... 目录同步调用WebApi方法Cls001类里面的写法总结控制台程序一般当作Job使用,有时候需要控制

Python用Flask封装API及调用详解

《Python用Flask封装API及调用详解》本文介绍Flask的优势(轻量、灵活、易扩展),对比GET/POST表单/JSON请求方式,涵盖错误处理、开发建议及生产环境部署注意事项... 目录一、Flask的优势一、基础设置二、GET请求方式服务端代码客户端调用三、POST表单方式服务端代码客户端调用四

基于Redisson实现分布式系统下的接口限流

《基于Redisson实现分布式系统下的接口限流》在高并发场景下,接口限流是保障系统稳定性的重要手段,本文将介绍利用Redisson结合Redis实现分布式环境下的接口限流,具有一定的参考价值,感兴趣... 目录分布式限流的核心挑战基于 Redisson 的分布式限流设计思路实现步骤引入依赖定义限流注解实现

Python跨文件实例化、跨文件调用及导入库示例代码

《Python跨文件实例化、跨文件调用及导入库示例代码》在Python开发过程中,经常会遇到需要在一个工程中调用另一个工程的Python文件的情况,:本文主要介绍Python跨文件实例化、跨文件调... 目录1. 核心对比表格(完整汇总)1.1 自定义模块跨文件调用汇总表1.2 第三方库使用汇总表1.3 导

SpringBoot结合Knife4j进行API分组授权管理配置详解

《SpringBoot结合Knife4j进行API分组授权管理配置详解》在现代的微服务架构中,API文档和授权管理是不可或缺的一部分,本文将介绍如何在SpringBoot应用中集成Knife4j,并进... 目录环境准备配置 Swagger配置 Swagger OpenAPI自定义 Swagger UI 底

SpringBoot实现RSA+AES自动接口解密的实战指南

《SpringBoot实现RSA+AES自动接口解密的实战指南》在当今数据泄露频发的网络环境中,接口安全已成为开发者不可忽视的核心议题,RSA+AES混合加密方案因其安全性高、性能优越而被广泛采用,本... 目录一、项目依赖与环境准备1.1 Maven依赖配置1.2 密钥生成与配置二、加密工具类实现2.1

使用Python的requests库调用API接口的详细步骤

《使用Python的requests库调用API接口的详细步骤》使用Python的requests库调用API接口是开发中最常用的方式之一,它简化了HTTP请求的处理流程,以下是详细步骤和实战示例,涵... 目录一、准备工作:安装 requests 库二、基本调用流程(以 RESTful API 为例)1.