代码之家  ›  专栏  ›  技术社区  ›  Zak

令牌认证路由的页面刷新重定向到React中的404页面

  •  0
  • Zak  · 技术社区  · 5 月前

    我有一个简单的应用程序,其中有一个登录页面,在提交表单后,它会向后端发出请求,后端在成功验证后返回一个令牌,然后重定向到内部仪表板页面。还有另一个页面称为设置,另一个是NotFound(404)页面。

    登录后,当我在仪表板页面或设置页面时,如果我刷新,它会把我带到404页面,而它应该留在我所在的页面上。有人知道问题是什么吗?

    代码如下:

    App.js
    
    const App = () => {
        const [isAuthenticated, setIsAuthenticated] = useState(false);
    
        const handleLogin = (token) => {
            localStorage.setItem('token', token);
    
            setIsAuthenticated(true);
        };
    
        useEffect(() => {
            const token = localStorage.getItem('token');
    
            setIsAuthenticated(!!token);
        }, []);
    
        return (
            <Router>
                {
                    isAuthenticated ? (
                        <Routes>
                            <Route path="/dashboard" element={
                                <Layout>
                                    <Dashboard />
                                </Layout>
                            } />
                            <Route path="/settings" element={
                                <Layout>
                                    <Settings />
                                </Layout>
                            } />
                            <Route path="*" element={<Layout><NotFound /></Layout>} />
                        </Routes>
                    ) : (
                        <Routes>
                            <Route path="/" element={<Login onLogin={handleLogin} />} />
                            <Route path="*" element={<Navigate to="/" />} />
                        </Routes>
                    )
                }
            </Router>
        );
    }
    
    Login.js
    
    const Login = ({ onLogin }) => {
        const [username, setUsername] = useState('');
        const [password, setPassword] = useState('');
        const navigate = useNavigate();
    
        const handleSubmit = async (e) => {
            e.preventDefault();
    
            const response = await fetch('/api/login', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({ username, password }),
            });
    
            if (response.ok) {
                const result = await response.json();
    
                if (result.success) {
                    localStorage.setItem('token', result.token);
    
                    onLogin(result.token);
                    navigate('/dashboard');
                }
            }
        };
    
        return (
            <div class="container">
                <div class="formContainer">
                    <h1>LOGIN</h1>
    
                    <form onSubmit={handleSubmit}>
                        <input
                            type="text"
                            value={username}
                            placeholder="username"
                            onChange={(e) => setUsername(e.target.value)}
                            required
                        />
    
                        <input
                            type="password"
                            value={password}
                            placeholder="password"
                            onChange={(e) => setPassword(e.target.value)}
                            required
                        />
    
                        <button type="submit" className="login-button">
                            Login
                        </button>
                    </form>
                </div>
            </div>
        );
    }
    
    1 回复  |  直到 5 月前
        1
  •  1
  •   Sowmo0509    5 月前

    对于您的案件, setIsAuthenticated useState 在React中异步设置。所以,最初你 isAuthenticated false ,它不会等你 setIsAuthenticated .


    可能的修复:

    1. 创建初始状态 null .
    const App = () => {
        const [isAuthenticated, setIsAuthenticated] = useState(null);
    
        const handleLogin = (token) => {
            localStorage.setItem('token', token);
    
            setIsAuthenticated(true);
        };
    
        useEffect(() => {
            if (isAuthenticated !== null) return;
            const token = localStorage.getItem('token');
    
            setIsAuthenticated(!!token);
        }, []);
    
    ...
    

    因此,在这种情况下,isAuthenticated不是false或未定义的,因此它将继续检查登录状态,如果是false,则自动转到登录页面。

    1. 在初始状态下直接分配本地存储:
     const [isAuthenticated, setIsAuthenticated] = useState(
            !!localStorage.getItem('token') // Initialize from localStorage
        );
    

    在这种情况下,令牌在初始加载时直接从本地存储中获取。