標頭與會話認證

沒有認證的專案僅使用 createHttpClient,必要時才附加 HeaderStore 和會話認證。


本頁的 commonService.ts 代碼是整個檔案的一部分

下面的 HeaderStore、headersProvider、sessionAuth 代碼不是獨立的檔案範例,而是專案共用 HTTP adapter(rxjsHttpService.ts/commonService.ts)的各部分的分開說明。如果想先查看整個檔案結構,請先檢查 HTTP 客戶端的最小完整型/擴展型的全部代碼,然後再閱讀本頁。

在瀏覽器中共享的標頭

像登錄後獲得的訪問令牌這樣需要多個服務共同使用的標頭可以HeaderStore保存在。

commonService.ts
ts
import { createHeaderStore } from "@byeolnaerim/typed-rx-http";

export const headerStore = createHeaderStore({
  "Content-Type": "application/json",
});

headerStore.merge({
  Authorization: `Bearer ${accessToken}`,
});

headerStore.remove("Authorization");

在 Next.js 中分開瀏覽器和伺服器的標頭

客戶端組件讀取 HeaderStore,伺服器組件則讀取 cookie。 headersProvider可以創建。此函數可以在一個地方分離 CSR 和 SSR 的標頭查詢方式。

commonService.ts
ts
const headersProvider = async () => {
  if (typeof window !== "undefined") {
    return headerStore.get();
  }

  const { cookies } = await import("next/headers");
  const accessToken = (await cookies()).get("accessToken")?.value;

  return accessToken
    ? { Authorization: `Bearer ${accessToken}` }
    : {};
};

export const service = createHttpClient<paths>({
  baseUrl: process.env.NEXT_PUBLIC_API_URL || "",
  headerStore,
  headersProvider,
});

如果需要 401 刷新,則包裝一次 callApi

不要逐一修改自動生成的服務,而是將會話操作符附加到公共callApi。這樣所有生成的服務都將使用相同的令牌查詢和刷新規則。

commonService.ts
ts
import { createSessionAuth } from "@byeolnaerim/typed-rx-http";
import { defer } from "rxjs";

const sessionAuth = createSessionAuth({
  headerStore,
  tokenUrl: "/api/auth/token",
  refreshUrl: "/api/auth/token/refresh",
  logoutUrl: "/api/auth/logout",
  onLoginChange: (loggedIn) => setLogin(loggedIn),
});

export const callApi = (serviceArguments) =>
  defer(() => service.callApi(serviceArguments)).pipe(
    sessionAuth.withSessionAuth(),
  );

如果沒有授權,則首先檢查令牌端點,並在原請求為 401 時刷新後再次請求。如果刷新也失敗,則調用登出端點並傳遞原始錯誤。

在不需要 refresh/retry 的情況下僅需要 token 同步的情況

若不使用 401 refresh/retry,僅在請求前同步 token,請使用 withEnsureToken()。

ts
return client.callApi(...).pipe(
  auth.withEnsureToken(),
);

如果不需要認證,

ts
export const { callApi, callApiStream } = createHttpClient<paths>({
  baseUrl: "/api",
});

公開 API 或簡單專案使用這個就足夠了。HeaderStore 和會話認證不是必需的結構。

© 2026 Byeolnaerim. 版權所有。介紹隱私政策