基本上,我遇到一个问题,如果有人要删除Cookie,我的路线将无法正常工作。我正在使用Auth0和React Router。
我不知道是为什么它跳过了if语句。不知道为什么不会被点击然后重定向到登录。
调试代码:
实际参考代码:
import React, { useEffect } from "react";
import history from "../history";
import { Route } from "react-router-dom";
import { useAuth0 } from '../auth/Auth';
const PrivateRoute = ({ component: Component, path, ...rest }) => {
debugger;
const { authenticated } = useAuth0();
useEffect(() => {
const fn = async () => {
console.log("authenticated", authenticated)
if (!authenticated || authenticated === null) {
history.replace('/login');
}
};
fn();
}, [authenticated, path]);
const render = props => <Component {...props} />;
return <Route path={path} render={render} {...rest} />;
};
export default PrivateRoute;
这是我App.js的精简版
import React, { useEffect } from "react";
import './App.scss';
import { Router, Route, Switch } from "react-router-dom";
import { Redirect } from "react-router";
import history from "./history";
import Home from "./scenes/Home/Home";
import Profile from "./scenes/Profile/Profile";
import SignUp from "./scenes/SignUp/SignUp";
import Login from "./scenes/SignUp/Login/Login";
import Dashboard from "./scenes/Dashboard/Dashboard";
import Account from "./scenes/Account/Account";
import Auth0Callback from "./scenes/Auth0Callback/Auth0Callback";
import { useAuth0 } from "./auth/Auth";
import PrivateRoute from "./components/PrivateRoute";
import PrivateRouteAuth from "./components/PrivateRouteAuth";
import NavBarMain from "./components/NavBarMain/NavBarMain";
import NavBarBasic from "./components/NavBarBasic/NavBarBasic";
import Footer from "./components/Footer/Footer";
import ScrollToTop from "./ScrollToTop";
// private route for main part of application
const NavRoute = ({ exact, path, component: Component }) => (
<PrivateRoute
exact={exact}
path={path} render={(props) => (
<>
<NavBarMain />
<Component {...props} />
<Footer />
</>
)} />
)
// private route for signup since need basic navbar
const NavRouteSignUp = ({ exact, path, component: Component }) =>
(
<PrivateRouteAuth
exact={exact}
path={path} render={(props) =>
(
<>
<NavBarBasic />
<Component {...props} />
<Footer />
</>
)} />
)
function App() {
const { renewSession, authenticated } = useAuth0();
useEffect(() => {
if (localStorage.getItem("auth") === "true") {
renewSession();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<div className="App">
<Router history={history}>
<ScrollToTop>
<Switch>
<Route exact path="/" render={() => (
authenticated ? (
<Route path="/" exact component={Home} />
) : (
<Redirect to="/login" />
)
)} />
{authenticated ? <NavRouteSignUp path="/signup" exact component={SignUp} /> : <NavRouteBase path="/signup" exact component={SignUp} />}
{authenticated ? <NavRouteSignUp path="/login" exact component={Login} /> : <NavRouteBase path="/login" exact component={Login} styleName="noBorder" />}
<Route path="/callback" render={(props) => {
return <Auth0Callback {...props} />
}} />
<NavRoute exact component={Dashboard} path="/progress" />
<NavRoute exact component={Profile} path="/profile" />
<NavRoute exact component={Account} path="/account" />
</Switch>
</ScrollToTop>
</Router>
</div>
);
}
export default App;
我的Auth.js与更新会话有关:
// logoout method removes all id's from local storage
const logout = () => {
console.log("the user is logging out");
// Remove tokens and expiry time
localStorage.removeItem('access_token')
localStorage.removeItem('id_token')
localStorage.removeItem('expires_at')
localStorage.removeItem('user')
localStorage.removeItem('auth')
localStorage.removeItem('selection')
setAuthenticated(null);
setUser(null);
history.push('/')
}
// method called once callback initiated
const handleAuthentication = () => {
console.log("auth0Client", auth0Client);
if (typeof window !== 'undefined') {
auth0Client.parseHash(async (err, authResult) => {
if (authResult && authResult.accessToken && authResult.idToken) {
console.log('inside the if authResult')
await setSession(authResult);
await howFarAlongIsUser();
} else if (err) {
console.log(err)
return err;
}
})
}
}
const isAuthenticated = () => {
if (typeof localStorage !== 'undefined') {
const expiresAt = JSON.parse(localStorage.getItem('expires_at'))
// setAuthenticated(true);
return new Date().getTime() < expiresAt
} else {
localStorage.setItem('auth', false)
return false
}
}
const setSession = async authResult => {
const expiresAt = JSON.stringify(
authResult.expiresIn * 1000 + new Date().getTime()
)
localStorage.setItem('access_token', authResult.accessToken)
localStorage.setItem('id_token', authResult.idToken)
localStorage.setItem('expires_at', expiresAt)
localStorage.setItem('auth', true)
setAuthenticated(true);
await new Bluebird(function (resolve, reject) {
auth0Client.client.userInfo(authResult.accessToken, (err, user) => {
if (err) return reject(err)
return resolve(user);
})
}).then(
data => {
localStorage.setItem('user', JSON.stringify(data))
setUser(data);
setAuthenticated(true);
}
)
}
const renewSession = async () => {
auth0Client.checkSession({}, async (err, authResult) => {
console.log("AUTH RESULT", authResult);
if (authResult && authResult.accessToken && authResult.idToken) {
await setSession(authResult);
} else if (err) {
console.log("loggin out inside renew session");
console.log("error", err);
logout();
}
});
}
const getUser = () => {
if (localStorage.getItem('user')) {
return JSON.parse(localStorage.getItem('user'))
}
}
答案 0 :(得分:0)
我能够通过完全删除useEffect并调用下面的if语句来修复它。我仍然对为什么顶级方法不起作用感到困惑。在删除本地存储之前,它工作正常。即使我看不到很多用户都在积极地这样做,但这种方式目前看来仍然可行:
const PrivateRoute = ({ component: Component, path, ...rest }) => {
const { authenticated } = useAuth0();
const render = props => <Component {...props} />;
return (
authenticated
? (<Route path={path} render={render} {...rest} />)
: (<Redirect to={{ pathname: '/login' }} />));
};
export default PrivateRoute;
我在想,也许useEffect中的异步函数要等到它最初呈现后才能完成运行。