RTK 查询 fetchBaseQuery 返回 FETCH_ERROR 而不是 401
RTK Query fetchBaseQuery returning FETCH_ERROR instead of 401
我有一个 TypeScript React front-end,使用 RTK 查询进行 API 调用。后端使用 AWS Cognito 进行身份验证。当用户的令牌过期时,我希望根据文档 automatic-re-authorization-by-extending-fetchbasequery
中的示例拦截 401,刷新令牌并触发原始请求
但是,我从 baseQuery 得到的结果是:
状态:FETCH_ERROR
错误:类型错误:获取失败
我希望收到 401 的 result.error.status,以便满足逻辑中的路径:-
const baseQuery = fetchBaseQuery({
baseUrl: `${process.env.BASE_URL}`,
prepareHeaders: (headers, { getState }) => {
const { accessToken } = (getState() as RootState).authentication.session;
if (accessToken) {
headers.set('authorization', 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 getFreshTokenFunction();
if (refreshResult) {
api.dispatch(setSession({ accessToken: refreshResult }));
// retry the initial query
result = await baseQuery(args, api, extraOptions);
} else {
api.dispatch(logout());
}
}
return result;
};
export const someApi = createApi({
reducerPath: 'someApi',
baseQuery: baseQueryWithReauth
.......
我得到 FETCH_ERROR 的事实让我想知道获取命令是否存在问题,但获取命令对于接收令牌然后获取数据的初始请求工作得很好。
在网络浏览器选项卡中失败的请求中,令牌过期后,我收到 200 pre-flight,然后是 401 提取。在控制台日志中,它显示“从源 *** 获取 *** 的访问已被 CORS 策略阻止:否 'Access-Control-Allow-Origin'”。如果这是一个 CORS 问题,我会感到惊讶,因为原始请求在令牌过期之前有效。
无论如何,非常感谢任何建议和帮助。谢谢!
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2022 年 4 月 6 日解决方案更新
最后,问题是,默认情况下,AWS API网关不提供 CORS 响应 headers。因此,当 UI 使用过期令牌从 API 请求数据时,来自 API 的响应 headers 缺少浏览器的 CORS headers寻找。前端逻辑失败,因为它没有正确接收 401 错误状态。我们的 API 网关是使用无服务器配置的,需要在此处进行更改 as follows
This ticket helped me towards the solution
我想说这可能真的是一个 CORS 问题。 RTK Query 的 fetchBaseQuery
只是调用 fetch
,而“TypeError: Failed to fetch”是一个 fetch-internal 错误消息,发生在 RTK Query 可以再次介入以解析响应或类似的东西之前。
我有一个 TypeScript React front-end,使用 RTK 查询进行 API 调用。后端使用 AWS Cognito 进行身份验证。当用户的令牌过期时,我希望根据文档 automatic-re-authorization-by-extending-fetchbasequery
中的示例拦截 401,刷新令牌并触发原始请求但是,我从 baseQuery 得到的结果是:
状态:FETCH_ERROR 错误:类型错误:获取失败
我希望收到 401 的 result.error.status,以便满足逻辑中的路径:-
const baseQuery = fetchBaseQuery({
baseUrl: `${process.env.BASE_URL}`,
prepareHeaders: (headers, { getState }) => {
const { accessToken } = (getState() as RootState).authentication.session;
if (accessToken) {
headers.set('authorization', 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 getFreshTokenFunction();
if (refreshResult) {
api.dispatch(setSession({ accessToken: refreshResult }));
// retry the initial query
result = await baseQuery(args, api, extraOptions);
} else {
api.dispatch(logout());
}
}
return result;
};
export const someApi = createApi({
reducerPath: 'someApi',
baseQuery: baseQueryWithReauth
.......
我得到 FETCH_ERROR 的事实让我想知道获取命令是否存在问题,但获取命令对于接收令牌然后获取数据的初始请求工作得很好。
在网络浏览器选项卡中失败的请求中,令牌过期后,我收到 200 pre-flight,然后是 401 提取。在控制台日志中,它显示“从源 *** 获取 *** 的访问已被 CORS 策略阻止:否 'Access-Control-Allow-Origin'”。如果这是一个 CORS 问题,我会感到惊讶,因为原始请求在令牌过期之前有效。
无论如何,非常感谢任何建议和帮助。谢谢!
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2022 年 4 月 6 日解决方案更新
最后,问题是,默认情况下,AWS API网关不提供 CORS 响应 headers。因此,当 UI 使用过期令牌从 API 请求数据时,来自 API 的响应 headers 缺少浏览器的 CORS headers寻找。前端逻辑失败,因为它没有正确接收 401 错误状态。我们的 API 网关是使用无服务器配置的,需要在此处进行更改 as follows
This ticket helped me towards the solution
我想说这可能真的是一个 CORS 问题。 RTK Query 的 fetchBaseQuery
只是调用 fetch
,而“TypeError: Failed to fetch”是一个 fetch-internal 错误消息,发生在 RTK Query 可以再次介入以解析响应或类似的东西之前。