bounty将在11小时后过期。回答此问题可获得+200声望奖励。mcclosa希望吸引更多人关注此问题。
在当前架构下尝试获取登录用户的Auth 0信息时遇到了一些问题。
我们有redux
和@reduxjs/toolkit
& react-redux
作为状态管理工具。
我们使用axios
通过redux-thunk操作发出HTTP请求。
现在,我们的应用程序中有一部分允许用户使用Auth0
注册/登录。
那么,我们的问题的一个例子。
目前,我们的redux商店设置了一些还原器
/* eslint-disable import/no-cycle */
import { configureStore } from '@reduxjs/toolkit';
import thunk from 'redux-thunk';
const createStore = (initialState?: any) => {
return configureStore({
reducer: {
// reducers are here
},
middleware: [thunk],
preloadedState: initialState,
});
};
export default createStore;
然后,我们将其附加到应用程序底部的Provider
import React from 'react';
import { Provider } from 'react-redux';
import createStore from '../store/createStore';
const App = () => {
return (
<Provider store={createStore()}>
//
</Provider>
);
};
export default App;
我们有一个axios示例函数,它使用axios
发出HTTP请求并处理错误。
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios';
import { getAuthSignature } from '../utils/auth';
export const API_URL = process.env.API_HOST;
const axiosInstance = async <T = any>(requestConfig: AxiosRequestConfig): Promise<AxiosResponse<T>> => {
const { token } = await getAuthSignature();
// I need to access auth0 data here
const { getAccessTokenSilently, isAuthenticated, isLoading, loginWithRedirect, user } = auth0;
if (!token) {
const tokenErr = {
title: 'Error',
message: 'Missing Authentication Token',
success: false,
};
throw tokenErr;
}
try {
let accessToken = token;
// Update authorization token if auth0 user
if(auth0) {
if(isAuthenticcation && user) accessToken = await getAccessTokenSilently({ audience });
else loginWithRedirect();
}
const result = await axios({
...requestConfig,
headers: {
...requestConfig.headers,
authorization: `Bearer ${accessToken}`,
},
});
return result;
} catch (error: any) {
if (error.response) {
if ([401, 403].includes(error.response.status)) {
window.location = '/';
}
const contentType = error?.response?.headers?.['content-type'];
const isHTMLRes = contentType && contentType.indexOf('text/html') !== -1;
const errObj = {
status: error?.response?.status,
statusText: error?.response?.statusText,
errorMessage: isHTMLRes && error?.response?.text && (await error?.response?.text()),
error,
};
throw errObj;
}
throw error;
}
};
export default axiosInstance;
这是一个thunk操作的例子,我们将使用上面提到的axios示例来发出HTTP请求。
import axios, { API_URL } from '../../services/axios';
import { Result } from '../../types/test';
import { AppThunk } from '../../store/store';
import { setResults, setResultsLoading, setTableLoading } from './test.slice';
type DefaultThunk = () => AppThunk<Promise<void>>;
const getResults: DefaultThunk = () => async () => {
dispatch(setTableLoading(true));
try {
const result = await axios<Result[]>(
{
method: 'GET',
url: `${API_URL}/test`,
},
);
dispatch(setResults(result.data));
} catch (err: any) {
console.log({ err });
} finally {
dispatch(setResultsLoading(false));
dispatch(setTableLoading(false));
}
};
export default getResults;
然后,我们分派thunk操作来发出HTTP请求并更新React组件中的reducer状态。
import React, { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import getResults from '../../reducers/test/test.thunk';
const TestComponent = () => {
const dispatch = useDispatch();
useEffect(() => {
dispatch(getResults());
}, []);
return (
//
);
};
export default TestComponent;
我的问题是,我不知道如何将Auth0
优雅地集成到当前流中,因此我不必在每个使用thunk操作的react组件中进行检查。
基本上,我需要从@auth0/auth0-react
访问useAuth0
钩子中的值,例如getAccessTokenSilently
、isAuthenticated
、user
和loginWithRedirect
。
我们不能在axios示例文件中使用useAuth0
钩子,因为它不是react组件/钩子,thunk文件也不是。
因此,我不确定如何以及在哪里获取数据,以便在axios文件中访问数据,如前所述,而不必在每个redux thunk操作中将其作为参数或其他东西传递。
也许我们只是需要一种不同的方法来处理当前的调度〉操作〉axios请求的流程?
有没有办法将这些数据作为中间件传递给redux?
任何帮助都将不胜感激。
1条答案
按热度按时间2w3rbyxf1#
我不相信你能够使用中间件来“嗅出”
auth0
上下文值,因为中间件运行在React的 * 外部a。这里我建议创建一个位于Auth0Provider
和reduxProvider
组件之间的 Package 器组件,该组件访问auth0
上下文,并分派一个操作将其保存到redux状态,在redux状态下可以通过useSelector
或直接从store.getState()
访问。幸运的是,
auth0
上下文值似乎已经存储在这里,因此它应该能够作为应用程序中的一个稳定引用直接使用。粗略示例:
创建并导出商店以在应用程序中使用。
商店
应用程序
建立新的Auth0状态磁盘片段。
在这里,您可以导入导出的
store
对象,并访问axios设置中的当前状态。