Skip to main content
Version: v4

TapTap OAuth Interface

Overview

TapTap OpenAPI uses a unified Mac Token header signature to transmit user authorization information.

When developers integrate the SDK login module, an access token (Access Token) is generated after the user authorizes your application. This access token is encrypted to generate a Mac Token string. The Access Token is valid for a long time and only becomes invalid when the user updates their account security information or revokes authorization for the current application. Developers should properly manage the Access Token on their server to serve as an identifier for subsequent communications with the TapTap server.

The Mac Token generation algorithm can be found in the MAC Token Algorithm section of the document.

Process

  1. Use SDK's TapTap login on the mobile terminal to obtain AccessToken, which includes:

    public String kid;
    public String token_type;
    public String mac_key;
    public String mac_algorithm;
    public Set<String> scopeSet;
  2. Send the parameters obtained from the mobile terminal to the game server, and the server-side calculates the mac token.

  3. Request https://openapi.tap.io/account/profile/v1, with the header carrying mac token.

API

When the SDK only requests the basic_info permission, use the basic information interface. When requesting public_profile, use the detailed information interface.

Get Current Account Basic Information

GET https://openapi.tap.io/account/basic-info/v1?client_id=xxx
Authorization mac token

Request Parameters

FieldTypeDescription
client_idstringThe application's Client ID, should match the agreement

Response Parameters

FieldTypeDescription
openidstringUnique identifier for authorized user, each player has a different openid in each game, the same game always retrieves the same openid for the same player
unionidstringUnique identifier for authorized user, the same unionid for a player across all games of a vendor, different unionid for different vendors

Request Example

Replace MAC id and Client ID with your calculated mac token and the Client ID from the console.

curl -s -H 'Authorization:MAC id="1/hC0vtMo7ke0Hkd-iI8-zcAwy7vKds9si93l7qBmNFxJkylWEOYEzGqa7k_9iw_bb3vizf-3CHc6U8hs-5a74bMFzkkz7qC2HdifBEHsW9wxOBn4OsF9vz4Cc6CWijkomnOHdwt8Km6TywOX5cxyQv0fnQQ9fEHbptkIJa
gCd33eBXg76grKmKsIR-YUZd1oVHu0aZ6BR7tpYYsCLl-LM6ilf8LZpahxQ28n2c-y33d-20YRY5NW1SnR7BorFbd00ZP97N9kwDncoM1GvSZ7n90_0ZWj4a12x1rfAWLuKEimw1oMGl574L0wE5mGoshPa-CYASaQmBDo3Q69XbjTs
KQ",ts="1618221750",nonce="adssd",mac="XWTPmq6A6LzgK8BbNDwj+kE4gzs="' "https://openapi.tap.io/account/basic-info/v1?client_id=<Client ID>"

Get Current Account Detailed Information

GET https://openapi.tap.io/account/profile/v1?client_id=xxx
Authorization mac token

Request Parameters

FieldTypeDescription
client_idstringThe application's Client ID, should match the agreement

Response Parameters

FieldTypeDescription
namestringUsername
avatarstringUser avatar image address
openidstringUnique identifier for authorized user, each player has a different openid in each game, the same game always retrieves the same openid for the same player
unionidstringUnique identifier for authorized user, the same unionid for a player across all games of a vendor, different unionid for different vendors

Request Example

Replace MAC id and Client ID with your calculated mac token and the Client ID from the console.

curl -s -H 'Authorization:MAC id="1/hC0vtMo7ke0Hkd-iI8-zcAwy7vKds9si93l7qBmNFxJkylWEOYEzGqa7k_9iw_bb3vizf-3CHc6U8hs-5a74bMFzkkz7qC2HdifBEHsW9wxOBn4OsF9vz4Cc6CWijkomnOHdwt8Km6TywOX5cxyQv0fnQQ9fEHbptkIJa
gCd33eBXg76grKmKsIR-YUZd1oVHu0aZ6BR7tpYYsCLl-LM6ilf8LZpahxQ28n2c-y33d-20YRY5NW1SnR7BorFbd00ZP97N9kwDncoM1GvSZ7n90_0ZWj4a12x1rfAWLuKEimw1oMGl574L0wE5mGoshPa-CYASaQmBDo3Q69XbjTs
KQ",ts="1618221750",nonce="adssd",mac="XWTPmq6A6LzgK8BbNDwj+kE4gzs="' "https://openapi.tap.io/account/profile/v1?client_id=<Client ID>"

Others

MAC Token Algorithm

MAC Token contains the following fields:

FieldTypeDescription
kidstringmac_key id, The key identifier.
token_typestringToken type, e.g., mac
mac_keystringmac key
mac_algorithmstringmac calculation algorithm name hmac-sha-1

Use Mac Token to sign an interface:

Node.js Request Example
const http = require('http');
const https = require('https');
const crypto = require('crypto');

function getAuthorization(requestUrl, method, keyId, macKey) {
const url = new URL(requestUrl);
const time = Math.floor(Date.now() / 1000).toString().padStart(10, '0');
const randomStr = getRandomString(16);
const host = url.hostname;
const uri = url.pathname + url.search;
const port = url.port || (url.protocol === 'https:' ? '443' : '80');
const other = '';
const sign = signData(mergeData(time, randomStr, method, uri, host, port, other), macKey);

return `MAC id="${keyId}", ts="${time}", nonce="${randomStr}", mac="${sign}"`;
}

function getRandomString(length) {
return crypto.randomBytes(length).toString('base64');
}

function mergeData(time, randomCode, httpType, uri, domain, port, other) {
let prefix =
`${time}\n${randomCode}\n${httpType}\n${uri}\n${domain}\n${port}\n`;

if (!other) {
prefix += '\n';
} else {
prefix += `${other}\n`;
}

return prefix;
}

function signData(signatureBaseString, key) {
const hmac = crypto.createHmac('sha1', key);
hmac.update(signatureBaseString);
return hmac.digest('base64');
}

const client_id = "5enu******wfy";
const keyId = "1/JFZi8****IiumsGZI31iJH1q*****UKZ-eKA";
const macKey = 'LMbNcKox*******kfmk7oWXbuRz';
const requestUrl = 'https://openapi.tap.io/account/profile/v1?client_id='+ client_id ;
const method = 'GET';

const authorization = getAuthorization(requestUrl, method, keyId, macKey);
console.log(authorization);

const options = new URL(requestUrl);
const client = options.protocol === 'https:' ? https : http;

const req = client.request({
hostname: options.hostname,
port: options.port,
path: options.pathname + options.search,
method: 'GET',
headers: {
'Authorization': authorization
}
}, (res) => {
let data = '';

res.on('data', (chunk) => {
data += chunk;
});

res.on('end', () => {
console.log(data);
});
});

req.end();


Java Request Example
package com.taptap;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.*;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public class Authorization {
public static void main(String[] args) throws IOException {
String client_id = "0RiAlMny7jiz086FaU";
String kid = "1/hC0vtMo7ke0Hkd-iI8-zcAwy7vKds9si93l7qBmNFxJkylWEOYEzGqa7k_9iw_bb3vizf-3CHc6U8hs-5a74bMFzkkz7qC2HdifBEHsW9wxOBn4OsF9vz4Cc6CWijkomnOHdwt8Km6TywOX5cxyQv0fnQQ9fEHbptkIJagCd33eBXg76grKmKsIR-YUZd1oVHu0aZ6BR7tpYYsCLl-LM6ilf8LZpahxQ28n2c-y33d-20YRY5NW1SnR7BorFbd00ZP97N9kwDncoM1GvSZ7n90_0ZWj4a12x1rfAWLuKEimw1oMGl574L0wE5mGoshPa-CYASaQmBDo3Q69XbjTsKQ"; // kid
String mac_key = "mSUQNYUGRBPXyRyW"; // mac_key
String method = "GET";
String request_url = "https://openapi.tap.io/account/profile/v1?client_id=" + client_id; //
String authorization = getAuthorization(request_url, method, kid, mac_key);
System.out.println(authorization);
URL url = new URL(request_url);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// Http
conn.setRequestProperty("Authorization", authorization);
conn.setRequestMethod("GET");
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
StringBuilder result = new StringBuilder();
while ((line = rd.readLine()) != null) {
result.append(line);
}
rd.close();
System.out.println(result.toString());
}
/**
* @param request_url
* @param method "GET" or "POST"
* @param key_id key id by OAuth 2.0
* @param mac_key mac key by OAuth 2.0
* @return authorization string
*/
public static String getAuthorization(String request_url, String method, String key_id, String
mac_key) {
try {
URL url = new URL(request_url);
String time = String.format(Locale.US, "%010d", System.currentTimeMillis() / 1000);
String randomStr = getRandomString(16);
String host = url.getHost();
String uri = request_url.substring(request_url.lastIndexOf(host) + host.length());
String port = "80";
if (request_url.startsWith("https")) {
port = "443";
}
String other = "";
String sign = sign(mergeSign(time, randomStr, method, uri, host, port, other), mac_key);
return "MAC " + getAuthorizationParam("id", key_id) + "," + getAuthorizationParam("ts", time)
+ "," + getAuthorizationParam("nonce", randomStr) + "," + getAuthorizationParam("mac",
sign);
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
private static String getRandomString(int length) {
byte[] bytes = new byte[length];
new SecureRandom().nextBytes(bytes);
String base64String = Base64.getEncoder().encodeToString(bytes);
return base64String;
}
private static String mergeSign(String time, String randomCode, String httpType, String uri,
String domain, String port, String other) {
if (time.isEmpty() || randomCode.isEmpty() || httpType.isEmpty() || domain.isEmpty() || port.isEmpty())
{
return null;
}
String prefix =
time + "\n" + randomCode + "\n" + httpType + "\n" + uri + "\n" + domain + "\n" + port
+ "\n";
if (other.isEmpty()) {
prefix += "\n";
} else {
prefix += (other + "\n");
}
return prefix;
}
private static String sign(String signatureBaseString, String key) {
try {
SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(signingKey);
byte[] text = signatureBaseString.getBytes(StandardCharsets.UTF_8);
byte[] signatureBytes = mac.doFinal(text);
signatureBytes = Base64.getEncoder().encode(signatureBytes);
return new String(signatureBytes, StandardCharsets.UTF_8);
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
throw new IllegalStateException(e);
}
}
private static String getAuthorizationParam(String key, String value) {
if (key.isEmpty() || value.isEmpty()) {
return null;
}
return key + "=" + "\"" + value + "\"";
}
}
PHP Request Example
<?php
/**
* The following are configuration items: please replace the parameters according to your actual situation before making an authorization request.
*/
$client_id = "Please replace with the Client ID from the console";
$kid = "Please replace with the kid value from the MAC Token after successful SDK authorization";
$mac_key = "Please replace with the mac_key value from the MAC Token after successful SDK authorization";

/**
* The API to get detailed information about the current account.
* If you need to get basic account information, replace with the following URL:
* https://openapi.tap.io/account/basic-info/v1
*/
$url = "https://openapi.tap.io/account/profile/v1";

/**
* Main program logic
*/
// Step 1: Set $method and $request_url
$method = "GET";
$request_url = $url . "?client_id=" . urlencode($client_id);

// Step 2: Generate timestamp and random number
$ts = time(); // Current timestamp in seconds
$nonce = randomString(5); // Random number, at least 5 characters

// Step 3: Create signing string and generate signature
$signing_string = createSigningString($request_url, $ts, $nonce, $method);
$mac = sign($signing_string, $mac_key);

// Step 4: Generate Authorization header information
$auth = sprintf('MAC id="%s",ts="%s",nonce="%s",mac="%s"', $kid, $ts, $nonce, $mac);
echo "Authorization: " . $auth . PHP_EOL . PHP_EOL;

// Step 5: Execute HTTP request and output the result
$headers = array("Authorization: " . $auth);
$response = executeCurlRequest($request_url, $headers, $method);

echo "HTTP Status Code: " . $response['http_code'] . PHP_EOL . PHP_EOL;
if (isset($response['error'])) {
echo "Error: " . $response['error'] . PHP_EOL . PHP_EOL;
}
if (isset($response['body'])) {
echo "Response Body: " . PHP_EOL . json_encode($response['body'], JSON_PRETTY_PRINT) . PHP_EOL;
}

/**
* Create the signing string
*
* @param string $request_url The request URL
* @param int $ts Timestamp
* @param string $nonce Random number
* @param string $method HTTP method
* @return string The signing string
*/
function createSigningString($request_url, $ts, $nonce, $method)
{
$parsed_url = parse_url($request_url);
$uri = $parsed_url['path'] . '?' . $parsed_url['query'];
$domain = $parsed_url['host'];
$port = 443; // Fixed port for HTTPS

return implode("\n", [
$ts,
$nonce,
$method,
$uri,
$domain,
$port,
""
]) . "\n";
}

/**
* Generate the signature value
*
* @param string $signing_string The signing string
* @param string $mac_key MAC key
* @return string The generated signature value
* @example sign('abc', 'def') -> dYTuFEkwcs2NmuhQ4P8JBTgjD4w=
*/
function sign($signing_string, $mac_key)
{
return base64_encode(hash_hmac('sha1', $signing_string, $mac_key, true));
}

/**
* Execute cURL request and return the result
*
* @param string $url The request URL
* @param array $headers Request headers
* @param string $method HTTP method
* @return array Contains the status code and response content or error information
*/
function executeCurlRequest($url, $headers, $method)
{
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

// Execute request and capture response
$response = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// Check for cURL errors
if (curl_errno($curl)) {
$error_message = curl_error($curl);
curl_close($curl);

return array(
'http_code' => 0,
'error' => "cURL error: " . $error_message,
'body' => json_decode($response, true)
);
}

// Close cURL handle
curl_close($curl);

// Parse response
$parsed_body = json_decode($response, true);

// Return result based on HTTP status code
if ($httpCode >= 200 && $httpCode < 300) {
return array(
'http_code' => $httpCode,
'body' => $parsed_body
);
} else {
return array(
'http_code' => $httpCode,
'error' => "HTTP request failed, status code: $httpCode",
'body' => $parsed_body
);
}
}

/**
* Generate a random string
*
* @param int $length The length of the random string
* @return string The randomly generated string
*/
function randomString($length = 5)
{
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';

for ($i = 0; $i < $length; $i++) {
$randomIndex = mt_rand(0, $charactersLength - 1);
$randomString .= $characters[$randomIndex];
}

return $randomString;
}

Python3 Request Example
import base64
import hmac
import random
import string
import time
from hashlib import sha1


def get_mac_token_signature(host, request_url, method, mac_key, kid):
mac_token_pattern = 'MAC id="{kid}",ts="{ts}",nonce="{nonce}",mac="{mac}"'
timestamp = str(int(time.time()))
nonce = ''.join(random.choices(string.ascii_lowercase + string.ascii_uppercase, k=16))
sign_array = [timestamp, nonce, method, request_url, host, '443', '']
seperator = '\n'
sign_input = seperator.join(sign_array) + seperator
hmac_code = hmac.new(mac_key.encode('UTF-8'), sign_input.encode('UTF-8'), sha1)
mac_str = base64.b64encode(hmac_code.digest()).decode('UTF-8')
return mac_token_pattern.format(kid=kid, ts=timestamp, nonce=nonce,
mac=mac_str)

if __name__ == '__main__':
kid = "1/hC0vtMo7ke0Hkd-iI8-zcAwy7vKds9si93l7qBmNFxJkylWEOYEzGqa7k_9iw_bb3vizf-3CHc6U8hs-5a74bMFzkkz7qC2HdifBEHsW9wxOBn4OsF9vz4Cc6CWijkomnOHdwt8Km6TywOX5cxyQv0fnQQ9fEHbptkIJagCd33eBXg76grKmKsIR-YUZd1oVHu0aZ6BR7tpYYsCLl-LM6ilf8LZpahxQ28n2c-y33d-20YRY5NW1SnR7BorFbd00ZP97N9kwDncoM1GvSZ7n90_0ZWj4a12x1rfAWLuKEimw1oMGl574L0wE5mGoshPa-CYASaQmBDo3Q69XbjTsKQ"
mac_key = "mSUQNYUGRBPXyRyW"
client_id = "0RiAlMny7jiz086FaU"
signature = get_mac_token_signature('openapi.tap.io', '/account/profile/v1?client_id=' + client_id,
'GET', mac_key, kid)
print(signature)
Go Request Example
package main

import (
"crypto/hmac"
"crypto/sha1"
"encoding/base64"
"fmt"
"io"
"net/http"
"strconv"
"time"
)

func main() {
// Replace clientId, accessToken, macKey parameters
// clientId parameter can be viewed in TapDC backend
clientId := "Replace with the `Client ID` from the console"
// kid returned by TapSDK after successful TapTap login
kid := "1/jvsVxFC6-PIUiXvZVVtv1hogX5q9Z1y_rp-AtVjE3iyHikXXfd_2h-i0wLmc9UjLJwhH6fQ8cvGrklONdvy2J5YfoqzV0ewGPMSLkQIkRv_xaLaYPariWbrkP1MtG2b4CzR1KHvuSCJHewCmTFZmsyNGojTJr5t75f5Nc8j-jjCYeDtFO0-XFI_J7kzktswzzsmISt7cx49QVess-VbaQcU31pEDb_OA03I28H5ehIvqQ0CQdf1LieLyONcH97l1IEU39AirioF_KGJccVG64QsgWmzxLPwmfTurw4cwBPo04yuXnas4YI5haE2UxtckNCpagP19drtGW57-HaAdww"
// mac_key returned by TapSDK after successful TapTap login
macKey := "fTCuDUDDmNny7a36EWbhUDLaqpoDMQu2hCi9qAJ5"

// Random number, replace when going live
nonce := "8IBTHwOdqNKAWeKl7plt66=="
// Convert timestamp to string
timestamp := strconv.FormatInt(time.Now().Unix(), 10)
// Request URL related
reqHost := "openapi.tap.io"
reqURI := "/account/profile/v1?client_id=" + clientId
reqURL := "https://" + reqHost + reqURI

macStr := timestamp + "\n" + nonce + "\n" + "GET" + "\n" + reqURI + "\n" + reqHost + "\n" + "443" + "\n\n"
mac := hmacSha1(macStr, macKey)
authorization := "MAC id=" + "\"" + accessToken + "\"" + "," + "ts=" + "\"" + timestamp + "\"" + "," + "nonce=" + "\"" + nonce + "\"" + "," + "mac=" + "\"" + mac + "\""

client := http.Client{}
req, err := http.NewRequest(http.MethodGet, reqURL, nil)
if err != nil {
fmt.Println(err.Error())
return
}

// Add request header
req.Header.Add("Authorization", authorization)
// Send request
resp, err := client.Do(req)
if err != nil {
fmt.Println(err.Error())
return
}
defer resp.Body.Close()

respBody, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println(string(respBody))
}

/*
HMAC-SHA1 Signature
*/
func hmacSha1(valStr, keyStr string) string {
key := []byte(keyStr)
mac := hmac.New(sha1.New, key)
mac.Write([]byte(valStr))

// Perform Base64 encoding
return base64.StdEncoding.EncodeToString(mac.Sum(nil))
}
C# Request Example

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.Text;

public class TapLoginOAuth : MonoBehaviour
{
private string host = "openapi.tap.io";
private string clientId = "Application's Client id";
private string macKey = "macKey value returned after client login";
private string kid = "kid value returned after client login";


// Start is called before the first frame update
void Start()
{
// Send network request
StartCoroutine(SendRequest());
}

// Update is called once per frame
void Update()
{

}

IEnumerator SendRequest()
{
// Construct request URL
string requestUrl = $"/account/profile/v1?client_id={clientId}";

// Generate signature
string signature = GetMacTokenSignature(host, requestUrl, "GET", macKey, kid);
Debug.Log("Generated Signature: " + signature);

// Send GET request to server
using (var httpClient = new HttpClient())
{
var uri = new Uri($"https://{host}{requestUrl}");
var request = new HttpRequestMessage(HttpMethod.Get, uri);
request.Headers.Add("Authorization", signature);

// Send request and wait for response
var response = httpClient.SendAsync(request).Result;
var responseBody = response.Content.ReadAsStringAsync().Result;

// Output server response
Debug.Log("Server Response: " + responseBody);
}

yield return null;
}
string GetMacTokenSignature(string host, string requestUrl, string method, string macKey, string kid)
{
string macTokenPattern = "MAC id=\"{0}\",ts=\"{1}\",nonce=\"{2}\",mac=\"{3}\"";
string timestamp = ((int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds).ToString();
string nonce = GenerateNonce(16);
string[] signArray = { timestamp, nonce, method, requestUrl, host, "443", "" };
string separator = "\n";
string signInput = string.Join(separator, signArray) + separator;

using (var hmac = new System.Security.Cryptography.HMACSHA1(Encoding.UTF8.GetBytes(macKey)))
{
byte[] hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(signInput));
string macStr = Convert.ToBase64String(hash);
return string.Format(macTokenPattern, kid, timestamp, nonce, macStr);
}
}

string GenerateNonce(int length)
{
const string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
var random = new System.Random();
var nonce = new char[length];

for (int i = 0; i < length; i++)
{
nonce[i] = chars[random.Next(chars.Length)];
}

return new string(nonce);
}
}

Shell Script Request Example

You can use this script to verify by directly replacing parameters to check if the mac token calculated by your server is correct.

Replace CLIENT_ID with the Client ID obtained from the console, and KID and MAC_KEY with the kid and mac_key obtained after successful client login:

#!/usr/bin/env bash

# Client ID
CLIENT_ID="Replace with the `Client ID` from the console"
# kid obtained from SDK
KID="1/hC0vtMo7ke0Hkd-iI8-zcAwy7vKds9si93l7qBmNFxJkylWEOYEzGqa7k_9iw_bb3vizf-3CHc6U8hs-5a74bMFzkkz7qC2HdifBEHsW9wxOBn4OsF9vz4Cc6CWijkomnOHdwt8Km6TywOX5cxyQv0fnQQ9fEHbptkIJa
gCd33eBXg76grKmKsIR-YUZd1oVHu0aZ6BR7tpYYsCLl-LM6ilf8LZpahxQ28n2c-y33d-20YRY5NW1SnR7BorFbd00ZP97N9kwDncoM1GvSZ7n90_0ZWj4a12x1rfAWLuKEimw1oMGl574L0wE5mGoshPa-CYASaQmBDo3Q69XbjTsKQ"
# mac_key obtained from SDK
MAC_KEY="mSUQNYUGRBPXyRyW"

# Random string, replace when going live
NONCE="8IBTHwOdqNKAWeKl7plt8g=="
# Current timestamp
TS=$(date +%s)

# Request method
METHOD="GET"
# Request URL (with query string)
REQUEST_URI="/account/profile/v1?client_id=${CLIENT_ID}"
# Request domain
REQUEST_HOST="openapi.tap.io"

MAC=$(printf "%s\n%s\n%s\n%s\n%s\n443\n\n" "${TS}" "${NONCE}" "${METHOD}" "${REQUEST_URI}" "${REQUEST_HOST}" | openssl dgst -binary -sha1 -hmac ${MAC_KEY} | base64)

AUTHORIZATION=$(printf 'MAC id="%s",ts="%s",nonce="%s",mac="%s"' "${KID}" "${TS}" "${NONCE}" "${MAC}")

curl -s -H"Authorization:${AUTHORIZATION}" "https://${REQUEST_HOST}${REQUEST_URI}"

Common Interface Error Information

Unified Format

FieldTypeDescription
codeintReserved field for future issue tracking
errorstringError code, used for logic judgment in the code
error_descriptionstringError description, used to help understand and resolve the error during development

Error Response

Error CodeDetailed Description
invalid_requestThe request is missing a required parameter, includes an unsupported parameter or parameter value, or is formatted incorrectly
invalid_timeThe ts time in MAC Token algorithm is invalid, request server time to reconstruct
invalid_clientThe client_id parameter is invalid
access_deniedThe authorization server denies the request This status occurs when requesting user resources with a token, if it appears, the client should exit the local user login information and guide the user to log in again
forbiddenThe user does not have permission for the current action, guiding re-authentication will not help, and this request should not be resubmitted
not_foundThe request failed, the requested resource was not found on the server. Under the same parameters, the request should not be repeated
server_errorAn exception occurred on the server Retry the request after a while, but there should be a retry limit, recommended maximum of 3 times, if it keeps failing, interrupt and inform the user
insufficient_scopeThe permission used for TapTap authorisation on the mobile side does not match the OAuth interface called by the server side, e.g. if the mobile side uses the basic_info permission for authorisation and the server side calls the `Get Current Account Detailed Information' API, then this exception is returned.