Studio GuideWorld SDK Guide
Log In

Creating a JWT authentication token for use with the open API

Open API request format

The ZEPETO open API is called via HTTP.

If a body is present in the request, parameters must be sent in JSON format.
Examples of valid content types are shown below, and there may be slight differences depending on the respective programming language library.

Content-Type: application/json; charset=utf-8

Get Access Key, Secret Key from ZEPETO Studio

Before creating a JWT authentication token, you need to get an access key and secret key from the ZEPETO Studio console.

📘

Please refer to the following guide. [Managing Open API]


Creating a JWT authentication token

ZEPETO open API generates a JWT(https://jwt.io) format token based on the access key and secret key issued for each request and sends it in the Authorization header.

HS256 is recommended as the signature method, and the secret to be used for signing is the issued secret key.

The JWT token payload has the following format:

{
    "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 is the hashed value of the uri including the query param except for the base path.
  • body_hash is the value converted to a json string and hashed to be inserted into the payload only when the request body exists; it is omitted if there is no request body.
    • In such a case, there should be no spaces between json string's key and value.
  • uri_hash and body_hash must be hashed to the same value as the query param and request body sent to the request. (The order of the values must be identical as well.)

❗️

Caution

  • Limit on number of API calls: Up to 300 calls are available in 1 minute.

Example when there is no request body

Please enter the access key, secret key, worldld, uri, and query param according to the API you wish to use.

The example code below has been written based on the Get Player Data API of the DataStorage category.

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}`;


Example when there is Request Body

Please enter the access key, secret key, worldld, uri, and body param according to the API you wish to use.

The example code below has been written based on the Set Player Data API of the DataStorage category.

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}`;

📘

Please refer to the following guide. [ZEPETO Studio API reference]

❗️

Caution

  • OpenAPI is a feature provided for use in a separate web or app.
  • Currently, ZEPETO server scripts cannot make ZEPETO Open API calls.
  • If you want to make Open API calls in ZEPETO multiplayer, we suggest the following methods:
    • Set up a separate server to perform the necessary business logic by communicating with the Open API.
    • Use the httpService package in ZEPETO server to communicate directly with the server you've set up.
    • Implement a relatively simple authentication method between servers, such as using HTTP Authorize headers, to enable calls within the supported features by ZEPETO server.