客戶端整合

最後更新

本頁說明瀏覽器與非瀏覽器客戶端如何送出 Token、接收續期後的新值。

瀏覽器(cookie)

Token 存在 httpOnly cookie,前端程式碼讀不到也不需要處理;只要請求帶上 cookie:

async function loadProfile() {
  const res = await fetch("https://api.example.com/me", {
    // 跨網域時必須帶上 cookie
    credentials: "include",
  });
  if (res.status === 401) {
    // 未登入或已登出
    window.location.href = "/login";
    return;
  }
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  return res.json();
}

續期由伺服器以 Set-Cookie 完成,前端無需額外處理。

非瀏覽器(header)

行動 App、CLI 或伺服器間呼叫不使用 cookie 時,以 header 送出,並從回應 header 更新本地值:

type Session = { accessToken: string; refreshId: string; deviceId: string };

async function callApi(session: Session, url: string) {
  const res = await fetch(url, {
    headers: {
      Authorization: `Bearer ${session.accessToken}`,
      "X-Refresh-ID": session.refreshId,
      // 納入指紋計算,必須與登入時相同
      "X-Device-ID": session.deviceId,
    },
  });

  const newToken = res.headers.get("X-New-Access-Token");
  const newRefreshId = res.headers.get("X-New-Refresh-ID");
  if (newToken) session.accessToken = newToken;
  if (newRefreshId) session.refreshId = newRefreshId;

  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  return res.json();
}

登入時 CreateJWT() 的回傳值 { token, refresh_id } 即為初始的 accessToken 與 refreshId。

注意事項

項目 說明
Device ID 由客戶端產生並持久保存(如安裝時產生的 UUID),每次請求相同
併發請求 Refresh ID 換發後舊 ID 只保留 5 秒;長時間離線後的大量併發請求應先以單一請求完成續期
回應 header 跨網域時伺服器需在 Access-Control-Expose-Headers 列出 X-New-Access-Token、X-New-Refresh-ID

相關:Token 傳遞、裝置指紋

EN