Auth0 Home Blog Docs

How to trigger a react method after jwt localStorage

jwt
react
localstorage

#1

I’m trying to use auth0 with a react app that talks to an auth0 graphQL api. I can log in successfully using the react auth0 tutorial that uses this auth0 class, but I am having trouble figuring out how I can initiate a react component method call that happens after the jwt is stored in localStorage. My code below has the standard auth0 class that was in the official tutorial followed by a main component and a navbar component. I instantiate the auth0 class in the main constructor and I’d really like to be able to call a react method in Main- essentially being able to call this.props.data.refetch() from main will solve my problems but only after the token is stored locally. How can I trigger this?

import auth0 from 'auth0-js';
import { AUTH_CONFIG } from './auth_variables';
import history from 'src/history';

export default class Auth {
  auth0 = new auth0.WebAuth({
    domain: AUTH_CONFIG.domain,
    clientID: AUTH_CONFIG.clientId,
    redirectUri: AUTH_CONFIG.callbackUrl,
    audience: 'http://localhost:5000',
    responseType: 'token id_token',
    scope: 'openid profile',
  });

  userProfile;

  constructor(query) {
    this.login = this.login.bind(this);
    this.logout = this.logout.bind(this);
    this.handleAuthentication = this.handleAuthentication.bind(this);
    this.isAuthenticated = this.isAuthenticated.bind(this);
    this.getAccessToken = this.getAccessToken.bind(this);
    this.getProfile = this.getProfile.bind(this);
    this._query = query;
  }

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

  handleAuthentication(query) {
    this.auth0.parseHash((err, authResult) => {
      if (authResult && authResult.accessToken && authResult.idToken) {
        this.setSession(authResult);
        history.push('/');
        query.refetch();
      } else if (err) {
        history.push('/');
        console.log(err);
        alert(`Error: ${err.error}. Check the console for further details.`);
      }
    });
  }

  setSession(authResult) {
    console.log('set session');
    console.log(authResult);
    // Set the time that the access token will expire at
    const expiresAt = JSON.stringify(authResult.expiresIn * 1000 + new Date().getTime());
    localStorage.setItem('access_token', authResult.accessToken);
    localStorage.setItem('id_token', authResult.idToken);
    localStorage.setItem('expires_at', expiresAt);
    // navigate to the home route
    history.push('/');
  }

  getAccessToken() {
    const accessToken = localStorage.getItem('access_token');
    if (!accessToken) {
      throw new Error('No access token found');
    }
    return accessToken;
  }

  getProfile(cb) {
    const accessToken = this.getAccessToken();
    this.auth0.client.userInfo(accessToken, (err, profile) => {
      if (profile) {
        this.userProfile = profile;
      }
      cb(err, profile);
    });
  }

  logout() {
    // Clear access token and ID token from local storage
    localStorage.removeItem('access_token');
    localStorage.removeItem('id_token');
    localStorage.removeItem('expires_at');
    this.userProfile = null;
    // navigate to the home route
    history.replace('/');
  }

  isAuthenticated() {
    // Check whether the current time is past the
    // access token's expiry time
    const expiresAt = JSON.parse(localStorage.getItem('expires_at'));
    return new Date().getTime() < expiresAt;
  }
}




@graphql(me)
class Main extends Component {
  constructor(props){
    super(props);
    this._auth = new Auth();
  }

  handleAuthentication(nextState, replace) {
    if (/access_token|id_token|error/.test(nextState.location.hash)) {
      this._auth.handleAuthentication();
    }
  }

  refetchMe() {
    this.props.data.refetch()
  }


  const { data, loading } = this.props;

  if (loading) {
  return <p>Loading</p>
  }

  
  return (
    <div>
      <Navbar auth={this._auth} user={data.me}/>
      <Grid fluid>
        <Switch>
          <Route path="/oneRoute/:id" component={MyRoutePage} />
          <Route
            path="/callback"
            render={props => {
              this.handleAuthentication(props);
              return <Callback {...props} />;
            }} />
        </Switch>
      </Grid>
    </div>
  )

}

 class Navbar extends Component {
  login = () => this.props.auth.login();
  logout = () => this.props.auth.logout();

  render() {
    return (
      <div>
        {this.props.user === undefined 
         ? <button onChange={this.login}>Login</button>
          : <button onChange={this.logout}>Logout</button>
        }
      </div>
    )
  }
}

#2