API参考
ZEPETO World Open API
为开放API创建JWT身份验证令牌
12分
ZEPETO开放API通过HTTP调用。
如果请求中存在主体,参数必须以JSON格式发送。 有效内容类型的示例如下,具体可能会根据各自的编程语言库略有不同。
Text
1Content-Type: application/json; charset=utf-8
在创建JWT身份验证令牌之前,您需要从ZEPETO Studio控制台获取访问密钥和秘密密钥。
📘 请参考以下指南。管理开放 API
ZEPETO开放API生成基于访问密钥和为每个请求发放的秘密密钥的JWT(https://jwt.io)格式令牌,并在Authorization头中发送。
推荐使用HS256作为签名方法,签名所用的秘密是发放的秘密密钥。
JWT令牌有效载荷具有以下格式:
JWT令牌有效载荷
1{
2 "access_key": "发放的访问密钥(必填)",
3 "nonce": "随机的UUID值(必填)",
4 "uri_hash": "URI的哈希值,包括查询参数,排除基本路径(必填)",
5 "body_hash": "请求体的哈希值"
6}
- uri_hash是包含查询参数的uri的哈希值,排除基本路径。
- body_hash是转换为json字符串并哈希的值,仅在请求体存在时插入到有效载荷中;如果没有请求体,则省略。
- 在这种情况下,json字符串的键和值之间不应有空格。
- uri_hash和body_hash必须与发送到请求的查询参数和请求体哈希到相同的值。(值的顺序也必须相同。)
- API调用数量限制:每分钟最多可进行300次调用。
请根据您希望使用的API输入访问密钥、秘密密钥、世界ID、URI和查询参数。
下面的示例代码是基于数据存储类别的获取玩家数据API编写的。
Java
1String accessKey = "accessKey";
2String secretKey = "secretKey";
3
4String worldId = "com.test.world";
5String uri = "/datastorage/v1/worlds/" + worldId + "/player-data";
6
7MessageDigest uriHash = MessageDigest.getInstance("SHA-256");
8uriHash.update(uri.getBytes(StandardCharsets.UTF_8));
9byte[] uriHashBytes = uriHash.digest();
10
11ObjectMapper objectMapper = new ObjectMapper();
12
13Map<String, Object> payload = new HashMap<>();
14payload.put("access_key", accessKey);
15payload.put("nonce", UUID.randomUUID().toString());
16payload.put("uri_hash", new String(Base64.encodeBase64(uriHashBytes), StandardCharsets.UTF_8));
17
18String jwtToken = Jwts.builder()
19 .setPayload(objectMapper.writeValueAsString(payload))
20 .signWith(SignatureAlgorithm.HS256, secretKey.getBytes(StandardCharsets.UTF_8))
21 .compact();
22
23String authorization = "Bearer " + jwtToken;
Python
1import jwt
2import uuid
3import hashlib
4import base64
5
6accessKey = 'accessKey'
7secretKey = 'secretKey'
8
9worldId = 'com.test.world'
10uri = '/datastorage/v1/worlds/' + worldId + '/player-data?playerId=testplayerid&keys=test'
11hash = hashlib.sha256()
12hash.update(uri.encode())
13
14payload = {
15 'access_key': accessKey,
16 'nonce': str(uuid.uuid4()),
17 'uri_hash': base64.b64encode(hash.digest()).decode('utf8')
18}
19
20jwt_token = jwt.encode(payload, secretKey)
21authorization = 'Bearer {}'.format(jwt_token)
TypeScript
1import * as jwt from 'jsonwebtoken';
2import * as uuid from 'uuid';
3import * as crypto from 'crypto-js';
4import { Buffer } from 'safe-buffer';
5
6const accessKey = 'accessKey';
7const secretKey = 'secretKey';
8const worldId = 'com.test.world';
9const uri = '/datastorage/v1/worlds/' + worldId + '/player-data?playerId=testplayerid&keys=test';
10const hash = crypto.SHA256(uri);
11
12const payload = {
13 access_key: accessKey,
14 nonce: uuid.v4(),
15 uri_hash: Buffer.from(hash.toString(), 'hex').toString('base64')
16};
17const jwtToken = jwt.sign(payload, secretKey);
18const authorization = `Bearer ${jwtToken}`;
19
请根据您希望使用的API输入访问密钥、秘密密钥、worldId、uri和body参数。
下面的示例代码是基于数据存储类别的设置玩家数据API编写的。
Java
1String accessKey = "accessKey";
2String secretKey = "secretKey";
3
4String worldId = "com.test.world";
5String uri = "/datastorage/v1/worlds/" + worldId + "/player-data";
6
7MessageDigest uriHash = MessageDigest.getInstance("SHA-256");
8uriHash.update(uri.getBytes(StandardCharsets.UTF_8));
9byte[] uriHashBytes = uriHash.digest();
10
11ObjectMapper objectMapper = new ObjectMapper();
12
13PlayerData dataMap = new PlayerData("test", "test value");
14
15List<PlayerData> dataList = new ArrayList<>();
16dataList.add(dataMap);
17
18PlayerDataSetParam param = new PlayerDataSetParam(dataList, "testplayerid");
19
20
21MessageDigest paramHash = MessageDigest.getInstance("SHA-256");
22paramHash.update(objectMapper.writeValueAsString(param).getBytes(StandardCharsets.UTF_8));
23byte[] paramHashBytes = paramHash.digest();
24
25Map<String, Object> payload = new HashMap<>();
26payload.put("access_key", accessKey);
27payload.put("nonce", UUID.randomUUID().toString());
28payload.put("uri_hash", new String(Base64.encodeBase64(uriHashBytes), StandardCharsets.UTF_8));
29payload.put("body_hash", new String(Base64.encodeBase64(paramHashBytes), StandardCharsets.UTF_8));
30
31String jwtToken = Jwts.builder()
32 .setPayload(objectMapper.writeValueAsString(payload))
33 .signWith(SignatureAlgorithm.HS256, secretKey.getBytes(StandardCharsets.UTF_8))
34 .compact();
35
36String authorization = "Bearer " + jwtToken;
Python
1import jwt
2import uuid
3import hashlib
4import base64
5import simplejson as json
6
7accessKey = 'accessKey' secretKey = 'secretKey'
8
9worldId = 'com.test.world'
10uri = '/datastorage/v1/worlds/' + worldId + '/player-data'
11hash = hashlib.sha256()
12hash.update(uri.encode())
13
14param = {
15 'playerId': 'testplayerid',
16 'data':[
17 {
18 'key': 'test',
19 'value': 'test value'
20 }
21 ]
22}
23
24param_hash = hashlib.sha256()
25param_hash.update(json.dumps(param, ensure_ascii=False, encoding='surrogatepass').encode())
26
27payload = {
28 'access_key': accessKey,
29 'nonce': str(uuid.uuid4()),
30 'uri_hash': base64.b64encode(hash.digest()).decode('utf8'),
31 'body_hash': base64.b64encode(param_hash.digest()).decode('utf8')
32}
33
34jwt_token = jwt.encode(payload, secretKey)
35authorization = 'Bearer {}'.format(jwt_token)
TypeScript
1import * as jwt from 'jsonwebtoken';
2import * as uuid from 'uuid';
3import * as crypto from 'crypto-js';
4import { Buffer } from 'safe-buffer';
5
6const accessKey = 'accessKey';
7const secretKey = 'secretKey';
8const worldId = 'com.test.world';
9const uri = '/datastorage/v1/worlds/' + worldId + '/player-data';
10const hash = crypto.SHA256(uri);
11
12const param = {
13 playerId: 'testplayerid',
14 data: [
15 {
16 value: 'test value',
17 key: 'test'
18 }
19 ]
20};
21const paramHash = crypto.SHA256(JSON.stringify(param,null,0));
22
23const payload = {
24 access_key: accessKey,
25 nonce: uuid.v4(),
26 uri_hash: Buffer.from(hash.toString(), 'hex').toString('base64'),
27 body_hash: Buffer.from(paramHash.toString(), 'hex').toString('base64')
28};
29const jwtToken = jwt.sign(payload, secretKey);
30const authorization = `Bearer ${jwtToken}`;
❗️ 注意
- OpenAPI 是一个可用于单独的网页或应用程序的功能。
- 目前,ZEPETO 服务器脚本无法进行 ZEPETO Open API 调用。
- 如果您想在 ZEPETO 多人游戏中进行 Open API 调用,我们建议以下方法:
- 设置一个单独的服务器,通过与 Open API 通信来执行必要的业务逻辑。
- 在 ZEPETO 服务器中使用 httpService 包直接与您设置的服务器进行通信。
- 在服务器之间实现相对简单的身份验证方法,例如使用 HTTP 授权头,以便在 ZEPETO 服务器支持的功能内进行调用。