React useEffect 在 JWT 身份验证后不更新重定向到安全路由的状态

问题描述 投票:0回答:1

我已经创建了一个安全路由/秘密,在我的反应应用程序中使用反应路由器,当有人登录时,我的应用程序通过 jwt 创建一个 cookie 并将其存储在用户的浏览器中,当有人点击此/秘密路由时,我的前端共享以下信息使用我的后端令牌并验证它是否有效(使用 jwt.verify),如果经过验证,我的后端会以状态 200 进行响应,我的前端将授予其查看 /secret 的权限,如果用户未经过验证,他将被重定向到 /login 路由再次登录。我已经使用 useState 使用 React 的 useEffect 钩子将重定向值设置为 true,但是我的 setRedirect 没有更新重定向变量,因此我将永远无法查看 /secret 路由,而是它总是将我重定向到 /login页。

这是我在 React 组件上的代码 /秘密

import { useState, useEffect } from "react";
import { Navigate } from "react-router-dom";

export default function SecretPage() {
    const [redirect, setRedirect] = useState(false);

useEffect(() => {
    async function authChecker() {
        try {
            const response = await fetch("http://localhost:4000/authenticate", {
                credentials: "include",
            });

            if (response.ok) {
                setRedirect(true); //IT IS NOT UPDATING
            } else {
                console.error('Authentication failed:', response.statusText);
            }
        } catch (error) {
            console.error('Error checking authentication:', error);
            // Handle error
        }
    }

    authChecker();
}, []);

if (!redirect) {
    return <Navigate to="/login" state={{ message: "You are not logged in, please login" }} />;
}

return (
    <h1>SecretPage</h1>
);
}

这是我在路由 http://localhost:4000/authenticate 上的后端函数

app.get("/authenticate", (req, res) => {
const token = req.cookies.jwt;
if (token) {
    jwt.verify(token, process.env.JWT_SECRET, (err, decoded) => {
        if (err) {
            console.error('Error verifying token:', err);
            return res.status(401).json({ message: 'Unauthorized' });
        } else {
            // Token is valid, allow access to protected resource
            return res.status(200).json({ message: 'Access granted' });
        }
    });
} else {
    res.status(401).json({ message: 'Unauthorized' });
}
});
reactjs react-hooks jwt
1个回答
0
投票

这是因为您重定向变量以 0 开头,您必须了解您的 API 响应不是立即的,但您的渲染会立即响应,从而使您的 if 块立即渲染您的 Redirect 组件。

我建议使用另一个 useState 来解决这个问题:

import { useState, useEffect } from "react";
import { Navigate } from "react-router-dom";

export default function SecretPage() {
    const [redirect, setRedirect] = useState(false);
    const [done, setDone] = useState(false);

useEffect(() => {
    async function authChecker() {
        try {
            const response = await fetch("http://localhost:4000/authenticate", {
                credentials: "include",
            });

            if (response.ok) {
                setRedirect(true); //IT IS NOT UPDATING
            } else {
                console.error('Authentication failed:', response.statusText);
            }
        } catch (error) {
            console.error('Error checking authentication:', error);
            // Handle error
        }
        setDone(true)
    }

    authChecker();
}, []);


if (!done) {
   return <div>Loading...</div>; 
}    

if (!redirect) {
    return <Navigate to="/login" state={{ message: "You are not logged in, please login" }} />;
}

return (
    <h1>SecretPage</h1>
);
}
© www.soinside.com 2019 - 2024. All rights reserved.