handleRedirectCallback fails on iOS (in Capacitor native app)
See original GitHub issueDescribe the problem
We want to build a native app wrapper with Capacitor around our Next.js website using this module. For authentication we want to open the Auth0 login dialog in the default browser of the device and after authentication redirect the user back into the native app. We tried this with deep links as well as with custom schemes to open our app again.
The problem we got is as following: Calling handleRedirectCallback with our callback url (containing a code and state value) is working on Android, but fails to work on iOS (16). (We can only assume it is because of how the Safari web view on iOS is treating security.)
What was the expected behavior?
The handleRedirectCallback should also succeed and not fail on iOS with an event.url as e.g. org.pftp.app://www1.plant-for-the-planet.org/login?code=***&state=***
await handleRedirectCallback(event.url).then(() => {
// do stuff here
}).catch((error) => {
});
Reproduction
We use this in our MR and it is always failing using e.g. the latest IOS 16 simulator using the latest version of this module with the following Auth0 application:
AUTH0_CUSTOM_DOMAIN=accounts.plant-for-the-planet.org
AUTH0_CLIENT_ID=6MME4DhfTZes2myvI0NXgWqGSIZdy0IH
Environment
Modules used:
"@auth0/auth0-react": "^1.11.0",
"@capacitor/android": "^4.0.1",
"@capacitor/app": "^4.0.1",
"@capacitor/core": "^4.0.1",
"@capacitor/ios": "^4.0.1",
"next": "^11.1.4",
"react": "^17.0.2",
Tested on:
- iOS 16 Simulator of iPhone 14
Issue Analytics
- State:
- Created a year ago
- Comments:10

Top Related StackOverflow Question
The reason we have
buildAuthorizeUrlandbuildLogoutUrlis for exactly this scenario, where you want to integrate with a Capacitor application (or some other framework that has its own native API for opening a browser.loginWithRedirectandlogoutwrap those two methods respectively, but the problematic part is that they usewindow.location.hrefto do the browser redirection part, which causes default browser app on your device to open, as opposed to what you really want to do, which is use Capacitor’s Browser plugin (which usesSFSafariViewControlleron iOS and Chrome Custom Tabs on Android). This provides a better experience for users and feels much more native within your application.hi @stevehobbsdev @norbertschuler on IOS Simulator didn’t get any issue, i just got an issue when do authorize using LINE, and LINE open the different safari. my temporary solution such like this
useEffect(() => { CapApp.addListener("appUrlOpen", async ({ url }) => { if (url.startsWith(callbackUri)) { if ( url.includes("state") && (url.includes("code") || url.includes("error")) ) { try{ const newurl = new URL(url); const searchParams = newurl.searchParams; //const res = await handleRedirectCallback(url) const newRes = await axios.post(${domain}/oauth/token,{grant_type:'authorization_code', client_id: clientId, client_secret:'your_secrete', code:searchParams.get('code'),redirect_uri:callbackUri}) console.log(newRes) // const res = await getAccessTokenSilently({'scope':'openid offline_access profile', audience:BASE_URL, detailedResponse: true, redirect_uri:callbackUri}); if(newRes){ const user = await axios.post(${domain}/userinfo,{}, {headers:{ 'Content-type':'application/x-www-form-urlencoded', 'Accept':'application/x-www-form-urlencoded', 'Authorization':Bearer ${newRes.data.access_token}}}) if(user?.data){ setUser(user.data) localStorage.setItem('profile', JSON.stringify(user.data)) } await Browser.close(); // doLogout() } } catch (err) { // await Browser.close(); console.log(err) } } } }); }, [handleRedirectCallback]);; because our auth0 using PKCE method, and doing some tricky on BE too. i do apologize if my language haven’t enough for you guys