> For the complete documentation index, see [llms.txt](https://qubic.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://qubic.gitbook.io/docs/guides/use-graphql/generate-headers.md).

# 產生 Headers

## 簽名

包含 Creator Storefront / Admin API 以及 Pass Admin API，只要是透過 GraphQL 呼叫的 APIs，都需要使用以下方法產生簽名。

## 標頭

Creator Admin API、Pass Admin API 以及 Creator Storefront API 要透過 key/secret 取得使用權限，需於通訊時在 header 中加入指定的屬性以完成驗證，描述如下：

| header 屬性       | 類型     | 說明                                   | 如何取得                                             |
| --------------- | ------ | ------------------------------------ | ------------------------------------------------ |
| x-qubic-api-key | string | API KEY                              | [聯絡 Qubic 團隊](https://www.qubic.market/#contact) |
| x-qubic-ts      | string | 運算當下的時間戳記                            | `Date.now().toString()`                          |
| x-qubic-sign    | string | 運算後的簽名                               | 範例                                               |
| Authorization   | string | 選填，使用 Storefront API 存取授權資料時，需要提供此資訊 | 範例                                               |

產生 API Key 時可以選擇是否採用安全性更高的 API 通訊機制，請依照是否有勾選使用對應的 Header 格式。\
接下來會提供 [標準範例](#biao-zhun-fan-li) 和 [高安全性的範例](#gao-an-quan-xing-de-fan-li) msg 的部分，標準不包含 body 本身，而高安全性是有包含的

<figure><img src="/files/rnhM9aHIod8S8meS4pwe" alt=""><figcaption></figcaption></figure>

## 標準範例

要被簽名的訊息不包含 request body

```
yarn add graphql-request graphql crypto-js      # yarn
npm install graphql-request graphql crypto-js   # npm
```

```typescript
import HmacSHA256 from "crypto-js/hmac-sha256.js";
import Base64 from "crypto-js/enc-base64.js";
import { request, gql } from "graphql-request";

const KEY = "YOUR_CREATOR_ADMIN_API_KEY";
const SECRET = "YOUR_CREATOR_ADMIN_API_SECRET";

const url = "https://creator.qubic.app/admin/graphql";

const urlObj = new URL(url);
const resource = `${urlObj.pathname}${urlObj.search}`; // output: /admin/graphql

const now = Date.now();
const msg = `${now}POST${resource}`;
const sig = HmacSHA256(msg, SECRET).toString(Base64);

const requestHeaders = {
  "x-qubic-api-key": KEY,
  "x-qubic-ts": now.toString(),
  "x-qubic-sign": sig,
};

const document = gql`
  query shop {
    shop {
      id
    }
  }
`;

const result = await request({
  url,
  document,
  requestHeaders,
});

console.log(result);
```

## 高安全性的範例

要被簽名的訊息中包含 request body

```
yarn add graphql-request graphql crypto-js      # yarn
npm install graphql-request graphql crypto-js   # npm
```

```typescript
import HmacSHA256 from "crypto-js/hmac-sha256.js";
import Base64 from "crypto-js/enc-base64.js";
import { request, gql, resolveRequestDocument } from "graphql-request";

const KEY = "YOUR_CREATOR_ADMIN_API_KEY";
const SECRET = "YOUR_CREATOR_ADMIN_API_SECRET";

const url = "https://creator.qubic.app/admin/graphql";

const urlObj = new URL(url);
const resource = `${urlObj.pathname}${urlObj.search}`; // output: /admin/graphql

const document = gql`
  query shop {
    shop {
      id
    }
  }
`;

const { operationName, query } = resolveRequestDocument(document);

const body = JSON.stringify({
  query,
  operationName,
});

const now = Date.now();
const msg = `${now}POST${resource}${body}`;
const sig = HmacSHA256(msg, SECRET).toString(Base64);

const requestHeaders = {
  "x-qubic-api-key": KEY,
  "x-qubic-ts": now.toString(),
  "x-qubic-sign": sig,
};

const result = await request({
  url,
  document,
  requestHeaders,
});

console.log(result);
```

## 單機版驗證簽名

這邊提供演算法例子，供參考用

### 標準簽名

```
yarn add crypto-js      # yarn
npm install crypto-js   # npm
```

```typescript
import HmacSHA256 from "crypto-js/hmac-sha256.js";
import Base64 from "crypto-js/enc-base64.js";

function sign(option) {
  const { now, method, resource, secret } = option;

  const msg = `${now}${method}${resource}`;
  const sign = HmacSHA256(msg, secret).toString(Base64);

  return { msg, sign };
}

const { msg, sign } = sign({
  now: 1689907490132,
  method: "POST",
  resource: "/admin/graphql",
  secret: "secret",
});

console.log(msg === "1689907490132POST/admin/graphql"); // true
console.log(sign === "d1tZksk8khiWQ+UTUY7m6u1Msb5Oyhfej+c384e5GM8="); // true
```

### 高安全性的簽名

```
yarn add crypto-js      # yarn
npm install crypto-js   # npm
```

```typescript
import HmacSHA256 from "crypto-js/hmac-sha256.js";
import Base64 from "crypto-js/enc-base64.js";

function signSec(option) {
  const { now, body, method, resource, secret } = option;

  const msg = `${now}${method}${resource}${body}`;
  const sign = HmacSHA256(msg, secret).toString(Base64);

  return { msg, sign };
}

const { msg, sign } = signSec({
  now: 1566549227549,
  body: "the_body",
  method: "PUT",
  resource: "/test/path?currency=USD",
  secret: "secret",
});

console.log(msg === "1566549227549PUT/test/path?currency=USDthe_body"); // true
console.log(sign === "xN/7FHzMvIVbJYESYPJlMwNHL9r3DBZ21lsjSn5W3Bo="); // true
```

## 常見問題

* 為何我一直收到 `{"error":{"code":404,"message":"resource not found"}}`？
  1. 請確認有將 [header 所需的資訊](#biao-tou)放入其中
  2. 請確認正在使用的 API key/secret 與 GraphQL endpoint 是匹配的
  3. 可以先試著寫[單機版程式驗證簽名](#chan-ji-ban-yan-zheng-qian-ming)是否正確
