【问题标题】:Authentication using React使用 React 进行身份验证
【发布时间】:2021-05-09 20:34:30
【问题描述】:

我正在做一个项目,在前端使用 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();
  }, [])

如果有任何我可以做的最佳解决方案,请告诉我! 谢谢

【问题讨论】:

  • 函数运行后isConnected 最终是否设置为 true?
  • @shn,是的,每次刷新,它先是假,然后是真
  • 您希望它自动成为true?假设需要 JWT 验证步骤,则存储的令牌可能会在不可避免的时间内无法验证。
  • @shn 好吧,起初它并没有引起任何问题,但是当我尝试访问我的 /Account 页面时,它会将我重定向到主页,因为 isConnected 是错误的,因为该页面重新加载..

标签: javascript reactjs authentication web


【解决方案1】:

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

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

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

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

【讨论】:

  • 感谢您的回答,我现在不是检查isConnected是否为真,而是检查令牌localStorage变量是否存在,您认为这是一件好事吗?
  • @AhmedZrouqui 看看这个文档,它会在这种情况下为您提供更多帮助hasura.io/blog/best-practices-of-using-jwt-with-graphql
  • @AhmedZrouqui 如果您得到了答案或 cmets 的帮助,请点赞,我将不胜感激。
【解决方案2】:

如果您的子组件依赖于令牌的有效性,您可以在 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 和网络应用程序的本质。

【讨论】:

  • 感谢您的回答,我现在不是检查isConnected是否为真,而是检查令牌localStorage变量是否存在,您认为这是一件好事吗?
  • 这确实取决于,但请记住,令牌的存在并不意味着其有效,甚至不意味着刷新令牌有效。
猜你喜欢
  • 2020-09-26
  • 2021-02-08
  • 2020-06-06
  • 2020-07-05
  • 1970-01-01
  • 1970-01-01
  • 2021-12-28
  • 2021-05-14
  • 2021-06-19
相关资源
最近更新 更多