Auth0 Home Blog Docs

Correct pattern for memory storage of jwts in react graphQL


#1

I’m following the Auth0-GraphQL blog post here and applying those patterns to my own code. I’m running into a problem where after I log in that I only get my jwt stored in memory after all the queries fire and the forceUpdate() doesn’t seem to be rerendering all the queries even if I set the query to ‘network-only’. I have read that Auth0 recommends that we only store tokens in memory, but all the official examples with react show storing tokens in local storage.

Has anyone had luck using class memory for storing their jwts?

class App extends React.Component {

  async componentDidMount() {
    window.jQuery = $;
    window.Tether = Tether;
    require('bootstrap');
    if (this.props.location.pathname === '/callback') return;
    try {
      await auth.silentAuth();
      console.log(auth.getAccessToken()) //this returns with the token
      this.forceUpdate(); //This fires but does not force rerun queries
    } catch (err) {
      if (err.error === 'login_required') return;
      console.log(err.error);
    }
  }

  render() {
    return (
      <div>
              <div>
                <BaseHelmet />
                <NavBar />
                <div className="container-fluid">
                  <Switch>
                    <Route exact path="/" component={HomePage} />
                    <GuardedRoute
                      path="/courses/:courseName/:sectionName/:lectureName"
                      component={LecturePage} />
      
                    <Route exact path="/callback" component={CallbackPage} />
                    <Route component={WhenNotFound} />
                  </Switch>
                </div>
                <Footer />
              </div>
      </div>
    );
  }
}

export default withRouter(App);


class Auth {
  constructor() {
    this.auth0 = new auth0.WebAuth({ ...PublicSettings.authSettings });
    this.authFlag = 'isLoggedIn';
    this.login = this.login.bind(this);
    this.logout = this.logout.bind(this);
    this.handleAuthentication = this.handleAuthentication.bind(this);
    this.isAuthenticated = this.isAuthenticated.bind(this);
  }

  login() {
    this.auth0.authorize();
  }

  getAccessToken() {
    return this.accessToken;
  }

  handleAuthentication() {
    return new Promise((resolve, reject) => {
      this.auth0.parseHash((err, authResult) => {
        if (err) return reject(err);
        if (!authResult || !authResult.accessToken) {
          return reject(err);
        }
        this.setSession(authResult);
        resolve();
      });
    });
  }

  setSession(authResult) {
    this.accessToken = authResult.accessToken;
    localStorage.setItem(this.authFlag, JSON.stringify(true));
  }

  logout() {
    localStorage.setItem(this.authFlag, JSON.stringify(false));
    this.auth0.logout({
      returnTo: homePage,
      clientID: PublicSettings.authSettings.clientID,
    });
  }

  silentAuth() {
    if (this.isAuthenticated()) {
      return new Promise((resolve, reject) => {
        this.auth0.checkSession({}, (err, authResult) => {
          if (err) {
            localStorage.removeItem(this.authFlag);
            return reject(err);
          }
          this.setSession(authResult);
          resolve();
        });
      });
    }
  }

  isAuthenticated() {
    return JSON.parse(localStorage.getItem(this.authFlag));
  }
}

const auth = new Auth();

export default auth;