【问题标题】:React Router: Check that JWT is valid before rendering a Private RouteReact Router:在渲染私有路由之前检查 JWT 是否有效
【发布时间】:2020-05-17 22:23:08
【问题描述】:

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

现在我正在向后端发送jwt 以检查它是否有效,然后再返回我要渲染的Component -- 如果jwt 身份验证失败,则RedirectLogin,或者render Dashboard 如果它是有效的jwt。问题是ProtectedRoutereturning redirect/login之前后端是returning 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" />
    }} />)
  }
}

【问题讨论】:

    标签: authentication react-router jwt


    【解决方案1】:

    我会说你需要一个经过身份验证/无效 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" />
        }} />)
      }
    }
    

    【讨论】:

    • 对于我认为很常见的问题,我无法在 SO、Youtube 或 Internet 上的任何其他地方找到解决方案,而您已经做到了。非常非常感谢。
    【解决方案2】:

    作为一种替代方式,您的后端 server.js 文件可以检查 jwt 是否有效并相应地发送状态代码。然后您的前端反应组件可以检查此状态代码并相应地呈现(或不呈现)页面。

    对于组件:

    import {useState, useEffect} from "react";
    const Private = () => {
    
      const [statusAuth, setStatusAuth] = useState(false);
      useEffect(() => {
        fetch("/privateroute")
        .then((res) => {
          if (res.status === 200) {
            setStatusAuth(true)
          } else {
            setStatusAuth(false)
          }
        });
      }, []);
      
      return(
        {statusAuth && <div>rendered page</div>}
        {!statusAuth && <div>You need to login. <Link to="/login"><span>Click for login page</span></Link></div>}
      )
    }
    

    对于 server.js 文件:

    app.get("/privateroute", function(req, res){
      const token = req.cookies.jwt;
      if (token) {
        jwt.verify(token, "signature-of-your-jwt-token", () => {
          res.status(200).end();
        })
      } else {
        res.status(404)
        res.send("Tokens didnt match");
      }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-24
      • 1970-01-01
      • 2017-12-20
      • 2018-01-06
      • 2020-07-10
      • 2020-08-13
      • 1970-01-01
      • 2018-03-07
      相关资源
      最近更新 更多