使用 React 进行身份验证

时间:2021-02-05 13:40:45

标签: javascript reactjs authentication web

我正在开发一个项目,前端使用 React,后端使用 Django。 我在 React 中使用了 useState 函数来处理 isConnected 变量。 我现在的问题是,每当我刷新网页时,isConnected 都会采用初始值,这是错误的,这是我的代码:


const [isConnected, setIsConnected] = useState(false)

useEffect( async () => {

    async function checkJWTValidity(){
      try{
        axios.defaults.headers.post['Authorization'] = "JWT "+localStorage.getItem("token")

        //fetching ME data from API
        const requestdata = await axios.post(
          utils.endpoint,{query: utils.meQuery}
        )
  
        //checking if the returned Data is NULL, if so, tokens would be deleted from localStorage.
        //else token variables will remain for its still valid.
        if(requestdata.data.data.me === null){
          const tokenItems = await getNewJWT(localStorage.getItem("refreshToken"))
          if(tokenItems.length === 0){
            localStorage.removeItem("token")
            localStorage.removeItem("refreshToken")
            setIsConnected(false)
            console.log("null")
          }
          else{
            localStorage.setItem("token", tokenItems[0])
            localStorage.setItem("refreshToken",  tokenItems[1])
            setIsConnected(true)
          }
        }
        else{
          console.log(isConnected)
          setIsConnected(true)
        }
      }
      catch(err){
          console.log(err)
      }
    }
  
    async function getNewJWT(refreshToken){
      const token = []
      try{
        //fetching refreshToken data from API
        const requestdata = await axios.post(
          utils.endpoint,
          {
            query: utils.refreshQuery(refreshToken)
          }
        )
  
        //checking if the returned Data is NULL, if so, tokens would be deleted from localStorage.
        //else token variables will remain for its still valid.
  
        if(requestdata.data.data.refreshToken.errors === null){
          token.push(requestdata.data.data.refreshToken.token.toString())
          token.push(requestdata.data.data.refreshToken.refreshToken.toString())
        }
        
      }
      catch(err){
          console.log(err)
      }
      return token
    }



    checkJWTValidity();
  }, [])

如果有我能做的最佳解决方案,请告诉我! 谢谢

2 个答案:

答案 0 :(得分:0)

每当刷新浏览器网页时,您的组件树和状态都会重置为初始状态。

要在浏览器中重新加载页面后保持以前的状态,您需要执行以下任一操作

  1. 在 localStorage 或 IndexedDB 中本地保存状态
  2. 或在服务器端重新加载。

并且你需要在初始化时添加代码来检查之前保存的本地状态或服务器状态,这样你就可以恢复之前的状态。

答案 1 :(得分:0)

如果您的子组件依赖于令牌的有效性,您可以在 isConnected 为 false 时阻止进一步渲染。通过这种方式,您可以给令牌时间刷新或确认。

const Auth = ({children}) => {
    const [isConnected, setIsConnected] = useState(false);

    useEffect(async () => {
        if (!isConnected) {
            async function checkJWTValidity() {
                // ...
            }
        }
    }, [isConnected]);

    return isConnected ? children : null;
};

我还在依赖项数组中添加了 isConnected 值,并在 useEffect 中放置了一个 if 语句。

总会有一个使用默认状态的时间点,无论时间有多短。这是 javascript 和网络应用的本质。