Auth0 React Hooks устанавливает состояние не обновляется - PullRequest
0 голосов
/ 31 октября 2019

В основном я перешел от использования локального хранилища к попытке использовать предоставленный вместо этого cookie-файл auth0, основываясь на том, что я прочитал о переполнении стека и форумах auth0 об использовании файлов cookie и локального хранилища. Я до сих пор не совсем уверен, что вместо этого гораздо безопаснее использовать cookie, но в основном, когда я вызываю 2 функции вплотную внутри handleAuthentication, вторая не использует обновленное значение user и authenticated, а вместо этого использует null, чтобы пользователиОшибка печати .sub не может прочитать свойство sub значения null.

Я так или иначе думаю, что он не обновляет значение сразу, или другая возможность - просто сбрасывает хуки useState на ноль каждый раз, когда получает функцию. Ниже приведены две функции, вызываемые в строке, и 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;
...