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>
)
}
}