Headers & Session Auth

没有认证的项目只使用createHttpClient,必要时才附加HeaderStore和session auth。


本页的 commonService.ts 代码是整个文件的一部分

下面的 HeaderStore、headersProvider、sessionAuth 代码并不是相互独立的文件示例,而是对项目公共 HTTP 适配器(rxjsHttpService.ts/commonService.ts)各部分的分开说明。如果想先查看整个文件结构,请查看 HTTP Client 的最小完整型/扩展型的完整代码,然后再阅读本页。

在浏览器中共享的header

像登录后获得的access token一样,多个服务需要共同使用的header可以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中分开浏览器和服务器的header

Client Component读取HeaderStore,Server Component读取cookie headersProvider可以创建。此函数可以在一个地方分离 CSR 和 SSR 的 header 查询方式。

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包裹一次

不要逐个修改自动生成的服务,而是将session operator附加到公共callApi。这样所有生成的服务将使用相同的token查询和刷新规则。

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(),
  );

如果没有Authorization,首先检查token endpoint,如果原请求是401,则在刷新后再次请求。如果刷新也失败,则调用logout endpoint并传递原始错误。

在不需要 refresh/retry 的情况下,仅需要 token 同步时

要在请求前仅同步 token,而不使用 401 refresh/retry,请使用 withEnsureToken()。

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

如果不需要认证

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

在公开API或简单项目中,这就足够了。HeaderStore和session auth不是必需的结构。

© 2026 Byeolnaerim. 保留所有权利.介绍隐私政策