Перехватчик запросов 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()};
}
}),