在尝试访问任何需要身份验证的组件时,如果未记录,我将尝试重定向到登录页面。 在尝试使用Firebase身份验证时,身份验证对象并不总是初始化的,并且延迟很小,因此根据文档,我必须使用onAuthStateChanged()事件侦听器,该侦听器都可以与显示已登录用户的导航栏一起正常使用。 但是,当尝试对已登录用户进行重定向时,由于始终未显示初始设置authuser的状态并且似乎已经进行了路由,因此始终显示初始登录对话框,因此无法正常工作。我在这里看到了类似的问题(Firebase, Avoid Logged-in user to visit login page),但当我直接进入url时,我并不能真正理解如何使用其中一个注释中的建议cookie /查询字符串,因为会话之间的初始延迟仍然很小值已设置并呈现,因此看不到第一次使用该方式将如何工作。对React来说是全新的,所以希望这个问题有意义。
PrivateRoute.js:
awk-mode
答案 0 :(得分:0)
我从未使用过Firebase,但我正在做类似的事情。
比方说,我有自定义的钩子,可以在其中获取令牌,登录和注销功能。
这是我的app.js样子。如果用户有权访问,我将获得令牌。如果授予访问权限,它将获得令牌,然后设置路由并重定向到管理控制台。
function App() {
const { token, login, logout } = useAuth();
let routes;
if (token) {
routes = (
<Switch>
<Redirect to="/dashboard" />
</Switch>
);
} else {
routes = (
<Switch>
<Redirect to="/login" />
<Route path="/" exact component={Layout} />
</Switch>
)
}
return (
<AuthContext.Provider
value={{
isLoggedIn: !!token,
token: token,
login: login,
logout: logout,
}}
>
<Navigation />
<Router>
<main>
{routes}
</main>
</Router>
</AuthContext.Provider>
);
}
这就是我的导航样子
const Navigation = () => {
const auth = useContext(AuthContext);
return (
<>
{ auth.isLoggedIn && (<AdminNavigation />) }
{ !auth.isLoggedIn && (<UserNavigation />) }
</>
);
};
这是我的登录组件的外观
const SignIn = () => {
const auth = useContext(AuthContext);
const classes = useStyles();
const {
// eslint-disable-next-line no-unused-vars
isLoading, error, sendRequest, clearError,
} = useHttpClient();
const [password, setPassword] = useState('');
const [email, setEmail] = useState('');
const [isLoggedIn, setIsLoggedIn] = useState(true);
const updateInput = (event) => {
if (event.target.id.toLowerCase() === 'email') {
setEmail(event.target.value);
} else {
setPassword(event.target.value);
}
};
const handleSwitchMode = () => {
setIsLoggedIn((prevMode) => !prevMode);
};
const authSubmitHandler = async (event) => {
event.preventDefault();
setIsLoggedIn(true);
// auth.login();
if (isLoggedIn) {
try {
const responseData = await sendRequest(
`${API_URL}/admin/login`,
'POST',
JSON.stringify({
email,
password,
}),
{
'Content-Type': 'application/json',
},
);
setIsLoggedIn(false);
auth.login(responseData.token);
} catch (err) {
setIsLoggedIn(false);
}
} else {
try {
const responseData = await sendRequest(
`${API_URL}/admin/signup`,
'POST',
JSON.stringify({
// name,
email,
password,
}),
{
'Content-Type': 'application/json',
},
);
auth.login(responseData.token);
} catch (err) {
clearError();
}
}
};
return (
<Container component="main" maxWidth="xs">
<div className={classes.paper}>
<Typography component="h1" variant="h5">
{isLoggedIn ? 'Login' : 'Sign up'}
</Typography>
<form className={classes.form} noValidate>
{!isLoggedIn && (
<TextField
variant="outlined"
margin="normal"
required
fullWidth
id="name"
label="Your name"
autoFocus
onChange={updateInput}
/>
)}
<TextField
variant="outlined"
margin="normal"
required
fullWidth
id="email"
label="Email Address"
name="email"
autoComplete="email"
autoFocus
value={email}
onChange={updateInput}
/>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
value={password}
autoComplete="current-password"
onChange={updateInput}
/>
<FormControlLabel
control={<Checkbox value="remember" color="primary" />}
label="Remember me"
/>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
onClick={authSubmitHandler}
>
{isLoggedIn ? 'Login' : 'Sign up'}
</Button>
<Grid container>
<Grid item xs>
<Link href="/" variant="body2">
Forgot password?
</Link>
</Grid>
<Grid item>
<Button
onClick={handleSwitchMode}
>
Dont have an account? Sign Up
</Button>
</Grid>
</Grid>
</form>
</div>
</Container>
);
希望这会有所帮助。