Auth0 React Hooks设置状态未更新

时间:2019-10-30 23:14:56

标签: reactjs state react-hooks auth0

基本上,我从使用本地存储转为尝试使用提供的auth0 cookie,而是根据我在堆栈溢出和auth0论坛中有关使用cookie与本地存储的所有内容阅读的内容。我仍然不能完全确定使用cookie是否更安全,但是基本上,当我在handleAuthentication内回接调用2个函数时,第二个函数不使用user和authenticated的更新值,而是使用null因此users.sub打印错误无法读取null的属性sub。

我在某种程度上在考虑要么不是立即更新值,要么是另一种可能是每次获取函数时都将useState挂钩重置为null。下面是连续调用的两个函数,howFarAlongIsUser是接收空值的函数。

 await setSession(authResult);
 await howFarAlongIsUser();

如何让第二个功能等待第一个功能的状态变化?

import React, { useContext, useState } from 'react'
import auth0 from 'auth0-js';
import history from '../history';
import { fetchUser } from '../api/api';
import config from "../config/auth_config.js";
import Bluebird from "bluebird";

export const Auth0Context = React.createContext();
export const useAuth0 = () => useContext(Auth0Context);

const Auth0Provider = (props) => {

  // how i used the previous state with local storage
  // const prevAuth = (window.localStorage.auth || null)
  // const prevUser = (window.localStorage.user || null)

  const [authenticated, setAuthenticated] = useState(null);
  const [user, setUser] = useState(null);
  const [authError, setAuthError] = useState(null);
  const [authLoginError, setAuthLoginError] = useState(null);
  const [passwordResetError, setPasswordResetError] = useState(null);

  // initialize auth client
  const auth0Client = new auth0.WebAuth({
    domain: config.domain,
    clientID: config.clientId,
    redirectUri: `${window.location.origin}/callback`,
    responseType: 'token id_token',
    scope: 'openid profile email',
  })

  // login method takes email password and db connection
  const login = async (email, password) => {
    console.log("the user called login method")
    await new Promise(function (resolve, reject) {
      auth0Client.login({
        "connection": 'Username-Password-Authentication',
        "email": email,
        "password": password,
      }, (err) => {
        console.log("ERROR", err);
        if (err) {
          if (err.code === "invalid_user_password" || err.code === "access_denied") {
            setAuthLoginError(["Your email address and password don’t match our records"])
          }
          else if (err.code === "too_many_attempts") {
            setAuthLoginError(["Account blocked for too many failed attempts.", "Check your email for instructions on how to unblock it."])
          }
          else {
            console.log('Something went wrong: ' + err.code)
            setAuthLoginError(["Hmm, that doesn't look right. Please try again."])
          }
          return reject(new Error(err.code))
        }
        else {
          console.log("INSIDE ELSE")
        }
      })
    })
  }

  // logout method
  const logout = () => {
    console.log("the user is logging out");
    history.push('/')
    setAuthenticated(null);
    setUser(null);
    auth0Client.logout({
      returnTo: `${window.location.origin}`
    });
  }

  const howFarAlongIsUser = async () => {
          // this is where the error occurs- user is undefined
          const data_1 = await fetchUser(user.sub);
         // business logic to determine where in flow
}

  // method called once callback initiated
  const handleAuthentication = async () => {
    console.log("auth0Client", auth0Client);
    console.log("window", window)
    if (typeof window !== 'undefined') {

      auth0Client.parseHash({ hash: window.location.hash }, async (err, authResult) => {

    if (authResult && authResult.accessToken && authResult.idToken) {
      console.log('inside the if authResult')
      await setSession(authResult);
      debugger;
      // THIS IS WHERE THE ERROR IS
      // howFarAlongIsUser does not have updated state of user and authenticated
      await howFarAlongIsUser();
    } else if (err) {
      console.log("error from parse hash", err)
      return err;
    }

      })
  }
  }


  const setSession = async authResult => {
    return await new Bluebird(function (resolve, reject) {
      return auth0Client.client.userInfo(authResult.accessToken, (err, user) => {
        if (err) return reject(err)
        return resolve(user);
      })
    }).then(
      data => {
        setUser(data);
        setAuthenticated(true);
      }
    ).catch(
      error => {
        console.log("error inside of set session", error)
      }
    )
  }

  const renewSession = async () => {
    return await new Bluebird(function (resolve, reject) {
      return auth0Client.checkSession({}, async (err, authResult) => {
        if (err) {
          return reject(err);
        }
        return resolve(authResult);
      })
    })
      .then(
        async authResult => {
          if (authResult && authResult.accessToken && authResult.idToken) {
            return await setSession(authResult);
          }
        }
      )
      .catch(err => {
        console.log("error", err);
        logout();
      })
  }

  return (
    <Auth0Context.Provider
      value={{
        login,
        logout,
        handleAuthentication,
        setSession,
        renewSession,
        authenticated,
        user,
        authError,
        authLoginError,
        howFarAlongIsUser
      }}
    >
      {props.children}
    </Auth0Context.Provider>
  );
}

export default Auth0Provider;

0 个答案:

没有答案