React Router:在渲染私有路由之前检查 JWT 是否有效

Sco*_*ott 1 authentication jwt react-router

我希望为React Router应用程序实现真实世界的身份验证。我见过的每个教程都fakeAuth用于模拟身份验证,但实际上并没有实现真实世界的身份验证。我正在尝试实际实施身份验证。这可能吗?

现在,我发送jwt给后端,以检查它是否在返回之前有效Component我想渲染-RedirectLogin如果jwt认证失败,或者render Dashboard如果它是有效的jwt。问题是ProtectedRoutereturn荷兰国际集团的redirect/login后端之前return荷兰国际集团是否jwt是有效还是无效。

如何在我的React-Router应用程序中获得真实世界的身份验证?这甚至可能吗?

const PrivateRoute = ({ component: Component, ...rest }) => {

  const [auth, setAuth] = useState(false);

  useEffect(() => {}, [auth])

  useEffect(() => {
    // send jwt to API to see if it's valid
    let token = localStorage.getItem("token");
    if (token) {
      fetch("/protected", {
        method: "POST",
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ token })
      })
      .then((res) => {
        return res.json()
      })
      .then((json) => {
        if (json.success) {
          setAuth(true);
        }
      })
      .catch((err) => {
        setAuth(false);
        localStorage.removeItem("token");
      });
    }

  }, [])

  return (<Route {...rest}
    render={(props) => {
      return auth ? <Component {...props} /> : <Redirect to="/login" />
    }} />)
  }
}

Run Code Online (Sandbox Code Playgroud)

Kac*_*992 5

我会说你需要一个在认证/无效 jwt 之间的状态。我会使用另一个状态字段,isTokenValidated(或 isLoading):

const PrivateRoute = ({ component: Component, ...rest }) => {

  const [auth, setAuth] = useState(false);
  const [isTokenValidated, setIsTokenValidated] = useState(false);

  useEffect(() => {
    // send jwt to API to see if it's valid
    let token = localStorage.getItem("token");
    if (token) {
      fetch("/protected", {
        method: "POST",
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ token })
      })
      .then((res) => {
        return res.json()
      })
      .then((json) => {
        if (json.success) {
          setAuth(true);
        }
      })
      .catch((err) => {
        setAuth(false);
        localStorage.removeItem("token");
      })
      .then(() => setIsTokenValidated(true));
    } else {
       setIsTokenValidated(true); // in case there is no token
    }

  }, [])

 if (!isTokenValidated) return <div />; // or some kind of loading animation

  return (<Route {...rest}
    render={(props) => {
      return auth ? <Component {...props} /> : <Redirect to="/login" />
    }} />)
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 对于我认为是一个非常常见的问题,我无法在 SO、Youtube 或互联网上的任何其他地方找到解决方案,而您已经做到了。非常、非常、非常感谢。 (2认同)