React登录后禁止访问登录页与首页的权限控制问题
解决方案
你的核心问题是登录状态更新与路由跳转的顺序错误,导致登录后公共路由的拦截逻辑未能及时生效。另外,调整部分组件逻辑可让状态与路由行为更一致。
问题分析
Login组件中,表单提交时先执行路由跳转再更新认证状态,跳转瞬间isUserAuthenticated仍为false,导致PublicRoutes无法触发拦截。Header的Logout按钮先跳转首页再更新状态,逻辑顺序不合理,可能引发不必要的路由渲染。
修改步骤
1. 修复Login组件提交逻辑
将认证状态更新放在表单提交逻辑中,确保状态更新完成后再执行跳转:
// Login.jsx import React from 'react' import { useState } from 'react' import { Container, Row, Col, Card, Form } from 'react-bootstrap' import { Navigate, useLocation, useNavigate } from 'react-router-dom' const Login = ({ isUserAuthenticated, userAuth }) => { const [username, setUsername] = useState("") const [password, setPassword] = useState("") const [umessage, setUM] = useState("Your username must be: Admin") const [pmessage, setPM] = useState("Your password must be: Admin") const location = useLocation() const navigate = useNavigate() const from = location.state?.from?.pathname || "/dashboard" const changeUsername = (e) => { setUsername(e.target.value) if (e.target.value === "Admin") setUM("Perfect") } const changePassword = (e) => { setPassword(e.target.value) if (e.target.value === "Admin") setPM("Perfect") } const enableButton = () => { return !(username === "Admin" && password === "Admin") } return isUserAuthenticated ? ( <Navigate to="/dashboard" replace /> ) : ( <Container className='mt-5'> <Row> <Col md="3"></Col> <Col md="6"> <Card> <Card.Header className='p-3' style={{ textAlign: 'center' }}> <h4>LOGIN HERE</h4> </Card.Header> <Card.Body> <Form onSubmit={(e) => { e.preventDefault() // 先更新认证状态,再执行跳转 userAuth() navigate(from, { replace: true }) }}> <Form.Group className="mb-3"> <Form.Control className="mb-2" type="text" required onChange={changeUsername} value={username} placeholder="Enter your username here" /> <Form.Text>{umessage}</Form.Text> <Form.Control className="mb-2" type="password" required onChange={changePassword} value={password} placeholder="Enter your password" /> <Form.Text>{pmessage}</Form.Text> <Form.Control className='btn btn-block btn-primary mb-3' disabled={enableButton()} type='submit' value="Login" /> </Form.Group> </Form> </Card.Body> </Card> </Col> <Col md="3"></Col> </Row> </Container> ) } export default Login
2. 优化PublicRoutes组件(简化写法)
// PublicRoutes.js import { Navigate, Outlet, useLocation } from 'react-router-dom' import React from 'react' const PublicRoutes = ({ isUserAuthenticated }) => { const location = useLocation() return isUserAuthenticated ? ( <Navigate to="/dashboard" state={{ from: location }} replace /> ) : ( <Outlet /> ) } export default PublicRoutes
3. 调整Header的Logout逻辑
先更新认证状态再跳转,避免无效路由渲染:
// Header.jsx import React from 'react' import { Container, Navbar, Nav } from 'react-bootstrap' import { Link, useNavigate } from 'react-router-dom' function Header({ loggedIn, userAuth }) { const navigate = useNavigate() const handleLogout = () => { userAuth() navigate('/', { replace: true }) } return ( <Navbar bg='dark' expand='lg' variant="dark"> <Container> <Link className='navbar-brand' to='/'>Server Tools</Link> <Navbar.Toggle aria-controls="basic-navbar-nav" /> <Navbar.Collapse id="basic-navbar-nav" className="justify-content-end"> <Nav className="ml-auto"> {loggedIn ? ( <> <Link className='nav-link' to='/dashboard'>Dashboard</Link> <button className='btn btn-success' onClick={handleLogout}>LOGOUT</button> </> ) : ( <Link className='btn btn-success' to='/login'>LOGIN</Link> )} </Nav> </Navbar.Collapse> </Container> </Navbar> ) } export default Header
验证效果
修改完成后:
- 登录成功后,手动输入
/或/login会自动跳转到/dashboard - 未登录时无法访问
/dashboard,会被重定向到登录页 - 登出后自动回到首页,且无法访问受保护路由
内容的提问来源于stack exchange,提问作者Subham Bhattacharya
相关产品推荐
相关产品推荐

