refresh-token-util-for-rtk-query
Version:
Reusable RTK Query baseQuery with refresh token
84 lines (73 loc) • 2.33 kB
text/typescript
import { fetchBaseQuery } from "@reduxjs/toolkit/query/react";
type AuthBaseQueryOptions<
TLoginRequest = any,
TLoginResponse = any,
TRefreshResponse = any
> = {
baseUrl: string;
refreshPath: string;
getAccessToken: () => string | null;
getRefreshToken: () => string | null;
saveTokens: (tokens: TLoginResponse | TRefreshResponse) => void;
clearTokens: () => void;
buildRefreshPayload?: (refreshToken: string) => Record<string, any>;
accessTokenResponseKey?: string;
refreshTokenResponseKey?: string;
};
export const createAuthBaseQuery = <
TLoginRequest = any,
TLoginResponse = any,
TRefreshResponse = any
>(
options: AuthBaseQueryOptions<TLoginRequest, TLoginResponse, TRefreshResponse>
) => {
const rawBaseQuery = fetchBaseQuery({
baseUrl: options.baseUrl,
prepareHeaders: (headers) => {
const token = options.getAccessToken();
if (token) {
headers.set("authorization", `Bearer ${token}`);
}
return headers;
},
});
const baseQueryWithReauth: typeof rawBaseQuery = async (
args,
api,
extraOptions
) => {
let result = await rawBaseQuery(args, api, extraOptions);
if (result.error && result.error.status === 401) {
const refreshToken = options.getRefreshToken();
if (!refreshToken) {
options.clearTokens();
return result;
}
const refreshResult = await rawBaseQuery(
{
url: options.refreshPath,
method: "POST",
body: options.buildRefreshPayload
? options.buildRefreshPayload(refreshToken)
: { refreshToken },
},
api,
extraOptions
);
if (refreshResult.data) {
const accessTokenKey = options.accessTokenResponseKey ?? "access_token";
const refreshTokenKey =
options.refreshTokenResponseKey ?? "refresh_token";
const data = refreshResult.data as Record<string, any>;
localStorage.setItem("access_token", data[accessTokenKey] ?? "");
localStorage.setItem("refresh_token", data[refreshTokenKey] ?? "");
localStorage.setItem("isLoggedIn", "true");
result = await rawBaseQuery(args, api, extraOptions);
} else {
options.clearTokens();
}
}
return result;
};
return baseQueryWithReauth;
};