qwe*_*ezz 7 reactjs auth0 react-router-dom
我正在尝试利用 React Router 加载器。实际上,除了一种情况之外,它的效果非常棒。
我用于Auth0 React SDK
授权。我传递getAccessTokenSilently
给axios interceptor
所有 API 调用,标头中都有不记名令牌。在某些路由上,我以这种方式使用 React Router v6.4 中的加载器:
路由器
{
path: PATHS.rawMedia,
element: <RawMediasPage />,
loader: rawMediasLoader,
}
Run Code Online (Sandbox Code Playgroud)
在我重新加载页面之前它工作得非常好。页面重新加载加载器在 Auth0 之前发送请求。在这种情况下,加载程序发送没有承载令牌的请求,并且从后端返回错误。
如何解决这个问题?高技能的人暗示我如何解决这个问题,但不幸的是我没那么好。据我了解,我需要在路由中进行<RouterProvider router={router} />
更App.tsx
深入的处理,以便 Auth0 首先针对令牌触发......但我不明白如何实现它。
AuthProvider.tsx
export const AuthProvider = (): JSX.Element | null => {
const navigate = useNavigate();
if (!(domain && clientId)) {
return null;
}
const onRedirectCallback = (appState: any) => {
navigate(appState?.returnTo || window.location.pathname);
};
return (
<Auth0Provider
domain={domain}
clientId={clientId}
redirectUri={window.location.origin}
onRedirectCallback={onRedirectCallback}
audience={audience}
>
<Outlet />
</Auth0Provider>
);
};
Run Code Online (Sandbox Code Playgroud)
受保护的路由.tsx
const ProtectedRoute = () => {
const location = useLocation();
const { isAuthenticated, isLoading, getAccessTokenSilently } = useAuth0();
useEffect(() => {
const getAccessToken = async () => {
try {
const token = await getAccessTokenSilently();
return Promise.resolve(token);
} catch (e) {
console.log('getAccessToken error:', e);
}
};
httpService(getAccessToken);
}, [getAccessTokenSilently]);
if (isLoading) {
return <Loader areaLoader />;
}
return isAuthenticated ? <Outlet /> : <Navigate to="/auth" state={{ from: location }} replace />;
};
Run Code Online (Sandbox Code Playgroud)
路由器
export const router = createBrowserRouter([
{
element: <AuthProvider />,
children: [
{
element: <ProtectedRoute />,
children: [
{
element: <InitApp />,
children: [
{
element: <BaseLayout />,
children: [
// many children with loaders
],
},
],
},
],
},
{
path: PATHS.auth,
element: <AuthPage />,
},
],
},
]);
Run Code Online (Sandbox Code Playgroud)
为了解决您的问题,您需要进行一些代码更改。我将一一介绍它们。请仔细查看文件扩展名。其中一些是,.ts
另一些是.tsx
。
AuthProvider.tsx
export const AuthProvider = = ({ children }: { children: any }) => {
const navigate = useNavigate();
if (!(domain && clientId)) {
return null;
}
const onRedirectCallback = (appState: any) => {
navigate(appState?.returnTo || window.location.pathname);
};
return (
<Auth0Provider
domain={domain}
clientId={clientId}
redirectUri={window.location.origin}
onRedirectCallback={onRedirectCallback}
audience={audience}
>
{children}
</Auth0Provider>
);
};
Run Code Online (Sandbox Code Playgroud)
索引.tsx
import { BrowserRouter as Router } from 'react-router-dom';
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<Router>
<AuthProvider>
<App />
</AuthProvider>
</Router>
);
Run Code Online (Sandbox Code Playgroud)
主路由.tsx
const MainRoutes = {
path: '/',
element: <MainLayout />,
children: [
{
path: '/',
element: <Home />
},
{
path: '/users',
element: <Users />
},
{
path: '/users/:id',
element: <AddEditUser />
},
{
path: '/roles',
element: <Roles />
},
{
path: '/roles/:id',
element: <AddEditRole />
},
]
};
export default MainRoutes;
Run Code Online (Sandbox Code Playgroud)
索引.ts
import { useRoutes } from 'react-router-dom';
import { withAuthenticationRequired } from '@auth0/auth0-react';
const ThemeRoutes = () => {
return useRoutes([MainRoutes]);
};
// This will protect all your routes at once.
export default withAuthenticationRequired(ThemeRoutes);
Run Code Online (Sandbox Code Playgroud)
应用程序.tsx
import { Provider } from 'react-redux';
import Routes from './routes';
import AppRoutes from './routes'; // This is mapped to index.ts
const App = () => {
// You can use getAccessTokenSilently here instead of getIdTokenClaims
const { user, getIdTokenClaims, isAuthenticated } = useAuth0();
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
const getUserMetadata = async () => {
setIsLoading(true);
const tokenData = await getIdTokenClaims();
if (tokenData) {
// use a interceptor in here
localStorage.setItem("token", tokenData['__raw']);
setIsLoading(false);
}
};
const storedAccessToken = localStorage.getItem("token");
if (!storedAccessToken) {
getUserMetadata();
}
}, [getIdTokenClaims, user]);
if (isAuthenticated && isLoading) {
return (
<div>Loading...</div>
);
}
return (
<Provider store={store}>
<Routes>
<AppRoutes />
</Routes>
</Provider>
);
};
export default App;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1834 次 |
最近记录: |