取得與使用 API Key
在 EasyAR 開發中心建立 API Key 無數量限制,建議為不同應用分配獨立的 API Key,以便更精細地管控權限。
建立 API Key
登入到 EasyAR 開發中心,若您是首次使用 API Key,請先建立一個 API Key,步驟如下:
- 在「授權」下,點擊「雲服務 API KEY」
- 在「API KEY」頁面點擊「建立 API KEY」按鈕

- 填寫「應用名稱」
- 根據您的應用需求勾選所需雲服務,不建議全部授權。
- 點擊「確定」
提示
使用 SpatialMap,勾選 SpatialMap。
使用雲識別,勾選雲識別。
使用 Mega Landmark,勾選 Mega Landmark,使用此功能前需向商務申請。
使用 AR 營運中心,勾選 AR 營運中心,使用此功能前需向商務申請。
使用 Mega Block 雲定位,勾選 Mega Block。

- 此時會在頁面生成 API Key 與 API Secret,如下圖所示,注意不要洩露。

警告
不要在用戶端(如 Web,微信小程式等)應用上直接使用 API Key 與 API Secret。
取得 token
有兩種方式可以取得 token:1. 從開發中心直接取得;2. 撰寫程式碼取得。若您對資源的存取權限有控制需求,建議使用第2種方式。下面將分別介紹這兩種取得方式,可根據您的需求自行選擇。
從開發中心取得 token
- 選擇一個您要使用的 API Key,點擊右側的「管理」

- 選擇一個 token 的有效期
- 點擊「產生 token」
- 點擊「複製」即可

附註
安全性是 token 有效期設定的首要原因。 若 token 有效期過長,一旦被洩露或竊取,攻擊者可長期使用,導致資料洩露或未授權操作;有效期限制了 token 的有效窗口,即使洩露,危害也僅限於短時間內。
使用 API Key 與 API Secret 產生 token
token 的產生過程要求核心參數進行簽章操作,確保傳輸安全性。隨後,這些簽章後的資料被發送到 STS(Security Token Service)服務進行身份驗證。STS 服務驗證通過後,會頒發一個臨時存取 token,該 token 僅在指定時間窗口內有效,逾時後需重新發起認證流程。
警告
不要在用戶端程式碼中產生 token,而是在伺服器端產生 token 後傳給用戶端使用。
請求參數
| 字段名 |
類型 |
是否必填 |
描述 |
| apiKey |
string |
是 |
API Key |
| expires |
int |
是 |
產生的 Token 有效時間, 單位為秒 |
| acl |
string |
是 |
存取控制清單 (Access Control List),控制 token 可存取資源權限 |
| timestamp |
long |
是 |
時間戳,單位為毫秒 |
| signature |
string |
是 |
簽章 |
acl:由一個或多個 AC(存取控制)組成,每個 AC 包含 service、effect、resource、permission 四個部分。
- service:服務類型,當前支援 ecs:crs(雲識別)、ecs:spatialmap(稀疏空間地圖)、ecs:cls(Mega Block 雲端定位)、ecs:vps1(landmark)
- resource:具體服務的 app id,例如雲識別庫的 CRS AppId
- effect:指定與該條 resource 配置項匹配的存取能否執行, 取值 Allow、Deny
- permission:權限取值 READ、WRITE
結構舉例如下:
[
{
"service": "ecs:crs",
"resource": ["f7ff497727ab2d55ea01d9984ef8068c"],
"effect": "Allow",
"permission": ["READ"]
}
]
簽章方法
- 將請求的所有參數按鍵名排序
- 對於每個參數,將其鍵名與值拼接成字串
- 將這樣得到的所有字串拼接,在最後拼上 API Secret
- 計算字串 sha256 雜湊的十六進位即為簽章
簽章範例
<?php
// 您的 API Key 與 API Secret
$apiKey = '6a47f7f8ff6......68744b4bcf';
$apiSecret = '87745d866345256b......fbae27c502a';
// 您的服務 App ID
$appId = 'f7ff497727ab2d55ea01d9984ef8068c';
// 有效時間, 單位為秒
$expires = 3600;
// 構建待簽名參數
$data = [
'apiKey' => $apiKey,
'expires' => $expires,
'acl' => '[{"service":"ecs:crs","resource":["'. $appId .'"],"effect":"Allow","permission":["READ"]}]',
'timestamp' => time() * 1000,
];
// 排序
ksort($data);
// 拼接字串
$builder = [];
foreach ($data as $key => $value) {
array_push($builder, $key . $value);
}
// 拼接 API Secret
array_push($builder, $apiSecret);
// 生成簽名
$signature = hash('sha256', implode('', $builder));
echo $signature;
const crypto = require('crypto');
// 您的 API Key 與 API Secret
const apiKey = '6a47f7f8ff6......68744b4bcf'
const apiSecret = '87745d866345256b......fbae27c502a'
// 您的服務 App ID
const appId = 'f7ff497727ab2d55ea01d9984ef8068c';
// 有效時間, 單位為秒
const expires = 3600
// 構建待簽名參數
const data = {
apiKey: apiKey,
expires: expires,
acl: `[{"service":"ecs:crs","resource":["${appId}"],"effect":"Allow","permission":["READ"]}]`,
timestamp: Date.now(),
}
// 排序與拼接字串
let builder = [];
Object.keys(data).sort().forEach(key => builder.push(`${key}${data[key]}`));
// 拼接 API Secret
builder.push(apiSecret);
// 生成簽名
const signature = crypto.createHash('sha256').update(builder.join('')).digest('hex');
console.info(signature);
import time
import hashlib
# 您的 API Key 與 API Secret
apiKey = '6a47f7f8ff6......68744b4bcf'
apiSecret = '87745d866345256b......fbae27c502a'
# 您的服務 App ID
appId = 'f7ff497727ab2d55ea01d9984ef8068c'
# 有效時間, 單位為秒
expires = 3600
# 建構待簽名參數
data = dict(sorted({
'apiKey': apiKey,
'expires': expires,
'acl': '[{"service":"ecs:crs","resource":["'+ appId +'"],"effect":"Allow","permission":["READ"]}]',
'timestamp': int(time.time() * 1000),
}.items()))
# 拼接字串
builder = [f'{key}{value}' for key, value in data.items()]
# 拼接 API Secret
builder.append(apiSecret)
# 產生簽名
signature = hashlib.sha256(''.join(builder).encode('utf8')).hexdigest()
print(signature)
package com.easyar;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.SortedMap;
import java.util.TreeMap;
public class App {
public static void main(String[] args) throws NoSuchAlgorithmException {
// 您的 API Key 與 API Secret
String apiKey = "6a47f7f8ff6......68744b4bcf";
String apiSecret = "87745d866345256b......fbae27c502a";
// 服務的 App ID
String appId = "f7ff497727ab2d55ea01d9984ef8068c";
// 有效時間, 單位為秒
int expires = 3600;
// 建構待簽名參數
SortedMap<String, Object> data = new TreeMap<>();
data.put("apiKey", apiKey);
data.put("expires", expires);
data.put("timestamp", System.currentTimeMillis());
data.put("acl", "[{\"service\":\"ecs:crs\",\"resource\":[\"" + appId + "\"],\"effect\":\"Allow\",\"permission\":[\"READ\"]}]");
// 拼接字串
StringBuilder builder = new StringBuilder();
data.forEach((key, value) -> builder.append(String.format("%s%s", key, value)));
// 拼接 API Secret
builder.append(apiSecret);
// 生成簽名
String signature = sha256(builder.toString());
System.out.println(signature);
}
private static String sha256(String str) throws NoSuchAlgorithmException {
StringBuilder builder = new StringBuilder();
MessageDigest digest = MessageDigest.getInstance("sha-256");
digest.update(str.getBytes(StandardCharsets.UTF_8));
byte[] bytes = digest.digest();
for (byte b : bytes) {
String hex = Integer.toHexString(b & 0XFF);
if (hex.length() == 1) {
builder.append("0");
}
builder.append(hex);
}
return builder.toString();
}
}
using System.Text;
using System.Security.Cryptography;
namespace EasyAR {
static class Program {
static void Main(string[] args) {
// 您的 API Key 與 API Secret
string apiKey = "6a47f7f8ff6......68744b4bcf";
string apiSecret = "87745d866345256b......fbae27c502a";
// 服務的 App ID
string appId = "f7ff497727ab2d55ea01d9984ef8068c";
// 有效時間, 單位為秒
int expires = 3600;
// 構建待簽名參數
SortedDictionary<string, object> data = new() {
{ "apiKey", apiKey },
{ "expires", expires },
{ "timestamp", DateTimeOffset.Now.ToUnixTimeMilliseconds() },
{ "acl", "[{\"service\":\"ecs:crs\",\"resource\":[\"" + appId + "\"],\"effect\":\"Allow\",\"permission\":[\"READ\"]}]" }
};
// 拼接字串
StringBuilder builder = new StringBuilder();
data.ToList().ForEach(pair => builder.Append($"{pair.Key}{pair.Value}"));
// 拼接 API Secret
builder.Append(apiSecret);
// 生成簽名
string signature = Sha256(builder.ToString());
Console.WriteLine(signature);
}
static string Sha256(string str) {
byte[] data = SHA256.HashData(Encoding.UTF8.GetBytes(str));
StringBuilder builder = new StringBuilder();
for (int i = 0; i < data.Length; i++) {
builder.Append(data[i].ToString("x2"));
}
return builder.ToString();
}
}
}
package main
import (
"crypto/sha256"
"fmt"
"sort"
"strings"
"time"
)
func main() {
// 您的 API Key 與 API Secret
apiKey := "6a47f7f8ff6......68744b4bcf"
apiSecret := "87745d866345256b......fbae27c502a"
// 您的服務 App ID
appId := "f7ff497727ab2d55ea01d9984ef8068c"
// 有效時間, 單位為秒
expires := 3600
// 構建待簽名參數
data := map[string]any{
"apiKey": apiKey,
"expires": expires,
"acl": `[{"service":"ecs:crs","resource":["` + appId + `"],"effect":"Allow","permission":["READ"]}]`,
"timestamp": time.Now().Unix() * 1000,
}
// 排序
keys := []string{}
for key := range data {
keys = append(keys, key)
}
sort.Strings(keys)
// 拼接字符串
builder := strings.Builder{}
for _, key := range keys {
builder.WriteString(fmt.Sprintf("%s%v", key, data[key]))
}
// 拼接 API Secret
builder.WriteString(apiSecret)
// 生成簽名
signature := fmt.Sprintf("%x", sha256.Sum256([]byte(builder.String())))
fmt.Println(signature)
}
提示
加入簽章時需要 ACL 轉換為 JSON 字串。
取得 token
將上述產生好的簽章加入到參數列表中,發送請求到 /token/v2 介面,取得 token。
- 請求地址:
https://uac.easyar.com/token/v2 或 https://uac-na1.easyar.com/token/v2 (北美1區)
- 請求方式:POST
- 請求頭:Content-Type: application/json
- 請求參數:
{"apiKey":"6a47f7f8ff6......68744b4bcf","expires":3600,"acl":"[{\"service\":\"ecs:crs\",\"resource\":[\"f7ff497727ab2d55ea01d9984ef8068c\"],\"effect\":\"Allow\",\"permission\":[\"READ\"]}]","timestamp":1765954279002,"signature":"32f18a37fc3c18......55c4943af9"}
示例如下:
curl -X POST https://uac.easyar.com/token/v2 \
-H 'Content-Type: application/json' \
-d '{"apiKey":"6a47f7f8ff6......68744b4bcf","expires":3600,"acl":"[{\"service\":\"ecs:crs\",\"resource\":[\"f7ff497727ab2d55ea01d9984ef8068c\"],\"effect\":\"Allow\",\"permission\":[\"READ\"]}]","timestamp":1765954279002,"signature":"32f18a37fc3c18......55c4943af9"}'
返回結果中如果 statusCode 為 0,則表示成功。
正常返回格式:
{
"statusCode": 0,
"timestamp": 1765954874399,
"msg": "Success",
"result": {
"apiKey": "6a47f7f8ff6......68744b4bcf",
"expires": 3600,
"token": "nuPDCj......xstQX",
"expiration": "2025-12-17T08:01:14.399+0000"
}
}
- token: 業務請求認證的 Token。
- expiration: token 的到期時間,過期後需重新申請 token。
錯誤返回格式:
{
"statusCode": 4001017,
"timestamp": 1765954666624,
"msg": "AppId is not authorized by this API Key",
"result": null
}
使用 token
在業務 https 請求中,將 token 加入請求頭,格式:{"Authorization": "nuPDCj......xstQX"}。
發送業務 API 請求時,需要添加參數 appId(取得出處請在開發中心查看相關服務)。
錯誤碼說明
在 token 產生與 token 使用過程中,可能會引發各類錯誤或異常情況。
為幫助開發者快速定位問題並採取有效解決措施,以下詳細說明常見錯誤碼及其含義:
| 錯誤碼 |
錯誤資訊 |
錯誤說明 |
解決方案 |
| 4001011 |
API Key invalid |
API Key 無效 |
查看「雲服務 API KEY」下是否有此 API Key |
| 4001012 |
Timestamp invalid |
時間戳無效 |
時間戳單位為毫秒,且與標準時間誤差不要超過 5 分鐘 |
| 4001015 |
Signature invalid |
簽章無效 |
檢查簽章演算法是否正確,以及查看 API Secret 與 API KEY 是否匹配 |
| 4001017 |
AppId is not authorized by this API Key |
API Key 未獲此 AppId 授權 |
檢查 AppId 所在的服務是否關聯到此 API Key |
| 4001018 |
Base64 decode error |
請求頭中設定的 Authorization 不是有效 base64 格式 |
取得的 token,不要作任何處理,直接使用 |
| 4001019 |
Decryption error |
請求頭中設定的 Authorization 不是 EasyAR 產生的 |
取得的 token,不要作任何處理,直接使用 |
| 4001022 |
API Key's resource is empty |
API Key 沒有關聯的雲服務 |
檢查 API Key 是否關聯了雲服務及關聯的雲服務是否已經過期 |
| 4001024 |
Token is expired |
token 已過期 |
重新產生 |
| 4001025 |
Token generate fail |
token 產生失敗 |
與技術支援聯繫:support@easyar.com |