Redux-Toolkit 查询拦截器
Redux-Toolkit query interceptor
我正在尝试为访问令牌因 RTK 查询而变得无效的情况构建一个拦截器。
我已经通过文档中的示例构建了它,因此看起来如下所示:
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/
需要一个带有刷新令牌的 POST
请求,我不知道如何重建这一行 const refreshResult = await baseQuery('token/refresh/', api, extraOptions);
让它接受参数并发出 POST
请求。
代替baseQuery('token/refresh/', api, extraOptions);
你也可以
baseQuery({
url: 'token/refresh/',
method: 'POST'
}, api, extraOptions);
fetchBaseQuery
的第一个参数正是您从端点定义中的 query
函数 return 得到的参数。
至于你的另一个问题,我不知道你所说的“public”和“私有”端点到底是什么意思。调用这些查询的是您的代码,因此您应该知道何时调用哪些查询?
我最近需要绕过将身份验证令牌添加到 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()};
}
}),
我正在尝试为访问令牌因 RTK 查询而变得无效的情况构建一个拦截器。 我已经通过文档中的示例构建了它,因此看起来如下所示:
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/
需要一个带有刷新令牌的 POST
请求,我不知道如何重建这一行 const refreshResult = await baseQuery('token/refresh/', api, extraOptions);
让它接受参数并发出 POST
请求。
代替baseQuery('token/refresh/', api, extraOptions);
你也可以
baseQuery({
url: 'token/refresh/',
method: 'POST'
}, api, extraOptions);
fetchBaseQuery
的第一个参数正是您从端点定义中的 query
函数 return 得到的参数。
至于你的另一个问题,我不知道你所说的“public”和“私有”端点到底是什么意思。调用这些查询的是您的代码,因此您应该知道何时调用哪些查询?
我最近需要绕过将身份验证令牌添加到 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()};
}
}),