การสร้างโทเค็นการตรวจสอบสิทธิ์ JWT เพื่อใช้กับ API เปิด
รูปแบบคำขอ API เปิด
API เปิดของ ZEPETO ถูกเรียกผ่าน HTTP.
หากมีเนื้อหาในคำขอ พารามิเตอร์จะต้องถูกส่งในรูปแบบ JSON. ตัวอย่างประเภทเนื้อหาที่ถูกต้องแสดงด้านล่าง และอาจมีความแตกต่างเล็กน้อยขึ้นอยู่กับไลบรารีภาษาการเขียนโปรแกรมที่เกี่ยวข้อง.
Content-Type: application/json; charset=utf-8
รับคีย์เข้าถึง, คีย์ลับจาก ZEPETO Studio
ก่อนที่จะสร้างโทเค็นการตรวจสอบสิทธิ JWT คุณต้องรับคีย์เข้าถึงและคีย์ลับจากคอนโซล ZEPETO Studio.
📘 กรุณาอ้างอิงจากคู่มือต่อไปนี้. การจัดการ Open API
การสร้างโทเค็นการตรวจสอบสิทธิ JWT
API เปิดของ ZEPETO สร้างโทเค็น JWT(https://jwt.io) ตามรูปแบบที่อิงจากคีย์เข้าถึงและคีย์ลับที่ออกให้สำหรับแต่ละคำขอและส่งในส่วนหัว Authorization.
HS256 เป็นวิธีการลงนามที่แนะนำ และความลับที่จะใช้ในการลงนามคือคีย์ลับที่ออกให้.
ข้อมูลใน JWT token มีรูปแบบดังต่อไปนี้:
{
"access_key": "issued access key (required)",
"nonce": "Randomized UUID value (required)",
"uri_hash": "A hashed value of the URI, including the query params, excluding the base path (required)",
"body_hash": "hashed value of the request body"
}
- uri_hash คือค่าที่ถูกแฮชของ uri รวมถึงพารามิเตอร์การค้นหา ยกเว้นเส้นทางหลัก.
- body_hash คือค่าที่ถูกแปลงเป็นสตริง json และถูกแฮชเพื่อแทรกลงใน payload เฉพาะเมื่อมีเนื้อหาการร้องขอ; จะถูกละเว้นหากไม่มีเนื้อหาการร้องขอ.
- ในกรณีเช่นนี้ จะต้องไม่มีช่องว่างระหว่างคีย์และค่าของสตริง json.
- uri_hash และ body_hash ต้องถูกแฮชให้มีค่าเหมือนกับพารามิเตอร์การค้นหาและเนื้อหาการร้องขอที่ส่งไปยังการร้องขอ (ลำดับของค่าต้องเหมือนกันด้วย).
- จำกัดจำนวนการเรียก API: สูงสุด 300 ครั้งใน 1 นาที.
ตัวอย่างเมื่อไม่มีเนื้อหาคำขอ
กรุณาใส่คีย์การเข้าถึง, คีย์ลับ, worldld, uri, และพารามิเตอร์การค้นหาตาม API ที่คุณต้องการใช้
โค้ดตัวอย่างด้านล่างนี้เขียนขึ้นตาม API ข้อมูลผู้เล่นของหมวดหมู่ DataStorage
Java
String accessKey = "accessKey";
String secretKey = "secretKey";
String worldId = "com.test.world";
String uri = "/datastorage/v1/worlds/" + worldId + "/player-data";
MessageDigest uriHash = MessageDigest.getInstance("SHA-256");
uriHash.update(uri.getBytes(StandardCharsets.UTF_8));
byte[] uriHashBytes = uriHash.digest();
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> payload = new HashMap<>();
payload.put("access_key", accessKey);
payload.put("nonce", UUID.randomUUID().toString());
payload.put("uri_hash", new String(Base64.encodeBase64(uriHashBytes), StandardCharsets.UTF_8));
String jwtToken = Jwts.builder()
.setPayload(objectMapper.writeValueAsString(payload))
.signWith(SignatureAlgorithm.HS256, secretKey.getBytes(StandardCharsets.UTF_8))
.compact();
String authorization = "Bearer " + jwtToken;
Python
import jwt
import uuid
import hashlib
import base64
accessKey = 'accessKey'
secretKey = 'secretKey'
worldId = 'com.test.world'
uri = '/datastorage/v1/worlds/' + worldId + '/player-data?playerId=testplayerid&keys=test'
hash = hashlib.sha256()
hash.update(uri.encode())
payload = {
'access_key': accessKey,
'nonce': str(uuid.uuid4()),
'uri_hash': base64.b64encode(hash.digest()).decode('utf8')
}
jwt_token = jwt.encode(payload, secretKey)
authorization = 'Bearer {}'.format(jwt_token)
NodeJS
import * as jwt from 'jsonwebtoken';
import * as uuid from 'uuid';
import * as crypto from 'crypto-js';
import { Buffer } from 'safe-buffer';
const accessKey = 'accessKey';
const secretKey = 'secretKey';
const worldId = 'com.test.world';
const uri = '/datastorage/v1/worlds/' + worldId + '/player-data?playerId=testplayerid&keys=test';
const hash = crypto.SHA256(uri);
const payload = {
access_key: accessKey,
nonce: uuid.v4(),
uri_hash: Buffer.from(hash.toString(), 'hex').toString('base64')
};
const jwtToken = jwt.sign(payload, secretKey);
const authorization = `Bearer ${jwtToken}`;
ตัวอย่างเมื่อมี Request Body
กรุณาใส่ access key, secret key, worldId, uri, และ body param ตาม API ที่คุณต้องการใช้
โค้ดตัวอย่างด้านล่างนี้เขียนขึ้นจาก Set Player Data API ของหมวด DataStorage
Java
String accessKey = "accessKey";
String secretKey = "secretKey";
String worldId = "com.test.world";
String uri = "/datastorage/v1/worlds/" + worldId + "/player-data";
MessageDigest uriHash = MessageDigest.getInstance("SHA-256");
uriHash.update(uri.getBytes(StandardCharsets.UTF_8));
byte[] uriHashBytes = uriHash.digest();
ObjectMapper objectMapper = new ObjectMapper();
PlayerData dataMap = new PlayerData("test", "test value");
List<PlayerData> dataList = new ArrayList<>();
dataList.add(dataMap);
PlayerDataSetParam param = new PlayerDataSetParam(dataList, "testplayerid");
MessageDigest paramHash = MessageDigest.getInstance("SHA-256");
paramHash.update(objectMapper.writeValueAsString(param).getBytes(StandardCharsets.UTF_8));
byte[] paramHashBytes = paramHash.digest();
Map<String, Object> payload = new HashMap<>();
payload.put("access_key", accessKey);
payload.put("nonce", UUID.randomUUID().toString());
payload.put("uri_hash", new String(Base64.encodeBase64(uriHashBytes), StandardCharsets.UTF_8));
payload.put("body_hash", new String(Base64.encodeBase64(paramHashBytes), StandardCharsets.UTF_8));
String jwtToken = Jwts.builder()
.setPayload(objectMapper.writeValueAsString(payload))
.signWith(SignatureAlgorithm.HS256, secretKey.getBytes(StandardCharsets.UTF_8))
.compact();
String authorization = "Bearer " + jwtToken;
Python
import jwt
import uuid
import hashlib
import base64
import simplejson as json
accessKey = 'accessKey' secretKey = 'secretKey'
worldId = 'com.test.world'
uri = '/datastorage/v1/worlds/' + worldId + '/player-data'
hash = hashlib.sha256()
hash.update(uri.encode())
param = {
'playerId': 'testplayerid',
'data':[
{
'key': 'test',
'value': 'test value'
}
]
}
param_hash = hashlib.sha256()
param_hash.update(json.dumps(param, ensure_ascii=False, encoding='surrogatepass').encode())
payload = {
'access_key': accessKey,
'nonce': str(uuid.uuid4()),
'uri_hash': base64.b64encode(hash.digest()).decode('utf8'),
'body_hash': base64.b64encode(param_hash.digest()).decode('utf8')
}
jwt_token = jwt.encode(payload, secretKey)
authorization = 'Bearer {}'.format(jwt_token)
NodeJS
import * as jwt from 'jsonwebtoken';
import * as uuid from 'uuid';
import * as crypto from 'crypto-js';
import { Buffer } from 'safe-buffer';
const accessKey = 'accessKey';
const secretKey = 'secretKey';
const worldId = 'com.test.world';
const uri = '/datastorage/v1/worlds/' + worldId + '/player-data';
const hash = crypto.SHA256(uri);
const param = {
playerId: 'testplayerid',
data: [
{
value: 'test value',
key: 'test'
}
]
};
const paramHash = crypto.SHA256(JSON.stringify(param,null,0));
const payload = {
access_key: accessKey,
nonce: uuid.v4(),
uri_hash: Buffer.from(hash.toString(), 'hex').toString('base64'),
body_hash: Buffer.from(paramHash.toString(), 'hex').toString('base64')
};
const jwtToken = jwt.sign(payload, secretKey);
const authorization = `Bearer ${jwtToken}`;
❗️ คำเตือน
- OpenAPI เป็นฟีเจอร์ที่ให้ใช้ในเว็บหรือแอปแยกต่างหาก
- ขณะนี้ สคริปต์เซิร์ฟเวอร์ ZEPETO ไม่สามารถเรียกใช้ ZEPETO Open API ได้
- หากคุณต้องการทำการเรียก Open API ใน ZEPETO multiplayer เราขอแนะนำวิธีการดังต่อไปนี้:
- ตั้งค่าเซิร์ฟเวอร์แยกต่างหากเพื่อดำเนินการตรรกะทางธุรกิจที่จำเป็นโดยการสื่อสารกับ Open API
- ใช้แพ็คเกจ httpService ในเซิร์ฟเวอร์ ZEPETO เพื่อสื่อสารโดยตรงกับเซิร์ฟเวอร์ที่คุณตั้งค่าไว้
- ดำเนินการวิธีการตรวจสอบสิทธิ์ที่ค่อนข้างง่ายระหว่างเซิร์ฟเวอร์ เช่น การใช้ HTTP Authorize headers เพื่อเปิดใช้งานการเรียกภายในฟีเจอร์ที่รองรับโดยเซิร์ฟเวอร์ ZEPETO