Auth0によるページの保護をReact Router v5からv6に変更
- Post AuthorBy pitang1965
- Post DateTue Nov 23 2021
次のコードが、react-router-domをv5からv6にアップグレードしたら、動かなくなりました(主題に無関係のコードもそのまま載せています)。
// App.jsx
import React, { useEffect } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import FooterMenu from './components/FooterMenu';
import { ThemeProvider } from 'styled-components';
import { StyledApp } from './styled/StyledApp';
import { GlobalStyle } from './styled/Global';
import { lightTheme, darkTheme } from './styled/Themes';
import useTheme from './hooks/useTheme';
import HomePage from './pages/HomePage';
import WorkshopPage from './pages/WorkshopPage';
import AboutPage from './pages/AboutPage';
import Navber from './components/Navbar';
import ProtectedRoute from './components/route/ProtectedRoute';
import toast, { Toaster } from 'react-hot-toast';
function App() {
const [theme, toggleTheme] = useTheme();
const currentTheme = theme === 'light' ? lightTheme : darkTheme;
useEffect(() => {
const ua = window.navigator.userAgent.toLowerCase();
if (ua.indexOf('safari') > 1 && ua.indexOf('chrome') === -1) {
toast.error(
'Safariはサポートされていません。ChromaかFirefoxを使用してください。',
{
icon: '�ȇ',
}
);
}
}, []);
return (
<Router>
<ThemeProvider theme={currentTheme}>
<GlobalStyle />
<StyledApp>
<Toaster />
<Navber toggleTheme={toggleTheme} />
<Switch>
<Route path='/about' component={AboutPage} />
<ProtectedRoute path='/workshop' component={WorkshopPage} />
<Route path='/' component={HomePage} />
</Switch>
<FooterMenu />
</StyledApp>
</ThemeProvider>
</Router>
);
}
export default App;
ここで、ProtectedRoute は次としていました。
// ProtectedRoute.jsx
import React from 'react';
import { Route } from 'react-router-dom';
import { withAuthenticationRequired } from '@auth0/auth0-react';
const ProtectedRoute = ({ component, ...args }) => (
<Route component={withAuthenticationRequired(component)} {...args} />
);
export default ProtectedRoute;
これをやめて、次のRequireAuthに変更しました。
// RequireAuth.jsx
import React from 'react';
import { useAuth0 } from '@auth0/auth0-react';
import LoginButton from '../LoginButton';
const RequireAuth = ({ children }) => {
const { isAuthenticated } = useAuth0();
return isAuthenticated ? (
children
) : (
<div>
<p>Twitter認証がされていないとこのページは見ることができません。</p>
<LoginButton />
</div>
);
};
export default RequireAuth;
App.jsx は次に変更しました。
// App.jsx
import React, { useEffect } from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import FooterMenu from './components/FooterMenu';
import { ThemeProvider } from 'styled-components';
import { StyledApp } from './styled/StyledApp';
import { GlobalStyle } from './styled/Global';
import { lightTheme, darkTheme } from './styled/Themes';
import useTheme from './hooks/useTheme';
import HomePage from './pages/HomePage';
import WorkshopPage from './pages/WorkshopPage';
import AboutPage from './pages/AboutPage';
import Navber from './components/Navbar';
import RequireAuth from './components/route/RequireAuth';
import toast, { Toaster } from 'react-hot-toast';
function App() {
const [theme, toggleTheme] = useTheme();
const currentTheme = theme === 'light' ? lightTheme : darkTheme;
useEffect(() => {
const ua = window.navigator.userAgent.toLowerCase();
if (ua.indexOf('safari') > 1 && ua.indexOf('chrome') === -1) {
toast.error(
'Safariはサポートされていません。ChromaかFirefoxを使用してください。',
{
icon: '�ȇ',
}
);
}
}, []);
return (
<Router>
<ThemeProvider theme={currentTheme}>
<GlobalStyle />
<StyledApp>
<Toaster />
<Navber toggleTheme={toggleTheme} />
<Routes>
<Route path='/about' element={<AboutPage/>} />
<Route path='/workshop' element={<RequireAuth><WorkshopPage /></RequireAuth>} />
<Route path='/' element={<HomePage/>} />
</Routes>
<FooterMenu />
</StyledApp>
</ThemeProvider>
</Router>
);
}
export default App;
この実装はAuth0に依存しているので、カスタムフックを使って更に改良していく予定です。