I’ve followed your recommendation by
- adjusting the
<Auth0Provider .../>
to include useRefreshTokens={true}
and cacheLocation="localstorage"
- ensured that any scopes are also passed into the Auth0Provider (yes we do use
getAccessTokenSilently
)
- we do actually use a custom domain
But it still seems to be stuck in an infinite redirect loop.
I’ve actually managed to isolate the issue into a new react app. (made with create-react-app)
index.js:
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import './index.css';
import { Auth0Provider } from "@auth0/auth0-react";
import config from './config.json';
const onRedirectCallback = (appState) => {
window.history.replaceState({}, document.title, appState && appState.targetUrl ? appState.targetUrl : window.location.pathname);
};
ReactDOM.render(
<Auth0Provider
connection={config.connection}
domain={config.domain}
clientId={config.clientId}
auddience={config.audience}
redirectUri={window.location.origin}
onRedirectCallback={onRedirectCallback}
useRefreshTokens={true}
cacheLocation="localstorage"
>
<App />
</Auth0Provider>,
document.getElementById("root")
);
App.js
import logo from "./logo.svg";
import "./App.css";
import { useAuth0 } from "@auth0/auth0-react";
import { useEffect } from "react";
import config from './config.json';
const App = () => {
const { isAuthenticated, isLoading, loginWithRedirect, logout, getAccessTokenSilently } = useAuth0();
useEffect(() => {
if(isLoading){
console.log('app is loading');
return;
}
if(!isAuthenticated){
console.log('not authenticated. redirecting to login');
loginWithRedirect();
return;
}
//this causes an infinite loop:
//getToken(config.customApi);
//this causes an infinite loop:
//getToken(config.managementApi);
//this works fine
getToken({});
}, [isLoading, isAuthenticated]);
const getToken = (options) => {
console.log(`retrieving token for '${options.audience}'`);
getAccessTokenSilently(options).then(token => {
console.log('retrieved token!', token);
})
.catch(e => {
console.error('failed to get token!', e);
});
};
if(isLoading){
return (<div>loading</div>);
}
if(!isAuthenticated){
return (<div>you're not authenticated!</div>);
}
const handleLogoutClick = (e) => {
e.preventDefault();
logout();
}
const render = () => {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<button onClick={handleLogoutClick}>Log out</button>
</header>
</div>
);
};
return render();
};
export default App;
config.json:
{
"connection": "app",
"domain": "ts-app-dev.au.auth0.com",
"clientId": "(my client id)",
"audience": "https://domain.com/api/v2/",
"customApi": {
"audience": "https://api.identifier"
},
"managementApi": {
"audience": "https://domain/api/v2/"
}
}
And the only package.json deps you need are:
"@auth0/auth0-react": "^1.5.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "4.0.3"
},
Above - if you uncomment the lines App.js, you’ll get an infinite loop.
It seems that if you provide the audience
option to getTokenSilently({ audience: ... )
, while in “incognito mode” you get stuck in an infinite loop.
Note: in auth0 management interface, i have
- a react app
- the auth0 management api (i dont use this except for allowing users to reset their password)
- a custom api (which contains all of my app’s functionality)
So i have 2 audiences (one for custom api, one for management api)
Any suggestions?
I can send you guys the fully zipped project + a log in for my app if you like.