Перехватчик запросов Redux-Toolkit

Я пытаюсь создать перехватчик для случаев, когда токен доступа становится недействительным с помощью RTK Query. Я построил его на примере из документации, он выглядит следующим образом:

      const baseQuery = fetchBaseQuery({
    baseUrl: BASE_URL,
    prepareHeaders: (headers, { getState }) => {
        const {
            auth: {
                user: { accessToken },
            },
        } = getState() as RootState;
        if (accessToken) {
            headers.set('authorization', `Bearer ${accessToken}`);
        }
        return headers;
    },
});

const baseQueryWithReauth: BaseQueryFn<string | FetchArgs, unknown, FetchBaseQueryError> = async (
    args,
    api,
    extraOptions
) => {
    let result = await baseQuery(args, api, extraOptions);

    if (result.error && result.error.status === 401) {
        const refreshResult = await baseQuery('token/refresh/', api, extraOptions);

        if (refreshResult.data) {
            api.dispatch(tokenUpdated({ accessToken: refreshResult.data as string }));

            // retry the initial query
            result = await baseQuery(args, api, extraOptions);
        } else {
            api.dispatch(logout());
        }
    }
    return result;
};

export const baseApi = createApi({
    reducerPath: 'baseApi',
    baseQuery: baseQueryWithReauth,
    endpoints: () => ({}),
});

Проблема в том, что token/refresh/ ожидает запроса с токеном обновления в своем теле, и я не могу понять, как восстановить эту строку const refreshResult = await baseQuery('token/refresh/', api, extraOptions); чтобы он принял параметры и сделал POST запрос.

2 ответа

Решение

вместо baseQuery('token/refresh/', api, extraOptions); вы также можете сделать

      baseQuery({
  url: 'token/refresh/',
  method: 'POST'
}, api, extraOptions);

Первый аргумент fetchBaseQuery это то, что вы бы вернули из query функция в определении конечной точки.

Что касается вашего другого вопроса, я не знаю, что именно вы подразумеваете под «общедоступными» и «частными» конечными точками. Эти запросы вызывает ваш код, поэтому вы должны знать, когда вызывать какие?

Мне недавно нужно было обойти добавление токена аутентификации в запрос refreshToken. Я сделал это, создав конечную точку, которая использовала queryFn, а не query:

      tokenRefresh: builder.query<TokenRefreshResponse, void>({
    queryFn: async (arg, queryApi, extraOptions, baseQuery) => {
        const response = await fetch(`/api/refresh`);
        return (response.ok) ? {data: await response.json()}
                             : {error: await response.json()};
    }
}),

Другие вопросы по тегам