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
tsimport { 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
tsconst 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
tsimport { 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不是必需的结构。