Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Access to fetch at external_redirect_url from origin our_url has been blocked due to CORS policy #320

Closed
hjhart opened this issue Mar 13, 2024 · 9 comments · Fixed by #325

Comments

@hjhart
Copy link

hjhart commented Mar 13, 2024

Expected behavior:

When tapping on a link that redirects to an external site
The external site should load correctly

Actual behavior:

Screenshot 2024-03-13 at 3 39 44 PM

"Error loading page" screen

Along with this in the Logcat output:

WebFragment onVisitErrorReceived() error code 0
[INFO:CONSOLE(0)] Access to fetch at 'https://our-app.formstack.com/forms/redacted' 
(redirected from 'http://app.android-local.dev-hellobrightline.com:3000/formstack/forms/3f76559e-bb49-4465-a7ab-ab4e75b80f29') 
from origin 'http://app.android-local.dev-hellobrightline.com:3000' has been blocked by CORS policy:
 No 'Access-Control-Allow-Origin' header is present on the requested resource. 
If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.", 
source: http://app.android-local.dev-hellobrightline.com:3000/formstack/forms/3f76559e-bb49-4465-a7ab-ab4e75b80f29 (0)

Isolating the problem further, if instead I have the original link pointing to https://our-app.formstack.com/forms/redacted instead of http://app.android-local.dev-hellobrightline.com:3000/formstack/forms/3f76559e-bb49-4465-a7ab-ab4e75b80f29, it works just fine. The introduction of the redirect seems to break it.

I noticed the CORS error in firefox and chrome, and disabling turbo fixed the request since it stopped being a fetch via turbo.js. Now it's happily a link that redirects successfully. But in our turbo-android app, it is still failing.

Since I don't have control over the formstack servers, I cannot modify the CORS headers successfully.

I'm going to continue to dive into this issue, but wanted to post it here for posterity, and to hopefully get some help from anyone who has encountered this issue previously.

Thanks in advance.

@MichalSznajder
Copy link
Contributor

You have to intercept navigations to external links and create a separate WebView to show them. WebView from Turbo is only intended to be used with turbo.js itself.

@hjhart
Copy link
Author

hjhart commented Mar 14, 2024

Thanks @MichalSznajder !

I already have some code doing that here:

interface NavDestination : TurboNavDestination {

   override fun shouldNavigateTo(newLocation: String): Boolean {
        Log.d("Navigation", "Navigation to ${newLocation} from ${location}")
        return when (isNavigable(newLocation)) {
            true -> true
            else -> {
                launchCustomTab(newLocation)
                false
            }
        }
    }

    private fun isNavigable(location: String): Boolean {
        return location.startsWith(BuildConfig.BASE_APP_URL)
    }

}

But the logging (Navigation to ${newLocation} from ${location}") only shows up on the first link.

So it shows up for my internal link, returns true, and continues within the WebView with turbo.js. However, it does not log the above after the redirect. So, that mechanism fails here. It's very possible I'm intercepting the requests at the wrong point in code, but if not, this is more internal to the turbo-android codebase than I've dug into.

I think we're getting closer. I'll keep looking through the docs to better understand if I'm intercepting the request properly.

@hjhart
Copy link
Author

hjhart commented Mar 27, 2024

I think I've verified that this is a bug in turbo-android. I've added this commit to a fork of the demo repository:

hjhart/turbo-native-demo@767139c

You can see how the external links work just fine, but a redirect to an external link does now. See the video below, running against a local server and using the default turbo-android demo code.

Screen.Recording.2024-03-27.at.12.01.32.PM.mov

This is what shows up in LogCat at the time:

2024-03-27 13:50:28.499 18141-18380 TurboLog                dev.hotwire.turbo.demo               D  visitProposedToLocation ........... [session: main, location: https://506f8e14c2c2.ngrok.app/follow-external-redirect, options: TurboVisitOptions(action=ADVANCE, snapshotHTML=null, response=null)]
2024-03-27 13:50:28.506 18141-18141 TurboLog                dev.hotwire.turbo.demo               D  shouldNavigateToLocation .......... [session: main, location: https://506f8e14c2c2.ngrok.app/follow-external-redirect, shouldNavigate: true, currentFragment: WebHomeFragment]
2024-03-27 13:50:28.511 18141-18141 TurboLog                dev.hotwire.turbo.demo               D  navigate .......................... [session: main, location: https://506f8e14c2c2.ngrok.app/follow-external-redirect, options: TurboVisitOptions(action=ADVANCE, snapshotHTML=null, response=null), currentContext: DEFAULT, newContext: DEFAULT, presentation: PUSH, currentFragment: WebHomeFragment]
2024-03-27 13:50:28.511 18141-18141 TurboLog                dev.hotwire.turbo.demo               D  navigateWithinContext ............. [session: main, location: https://506f8e14c2c2.ngrok.app/follow-external-redirect, presentation: PUSH, currentFragment: WebHomeFragment]
2024-03-27 13:50:28.547 18141-18141 TurboLog                dev.hotwire.turbo.demo               D  navigateToLocation ................ [session: main, location: https://506f8e14c2c2.ngrok.app/follow-external-redirect, uri: turbo://fragment/web, currentFragment: WebHomeFragment]
2024-03-27 13:50:28.564 18141-18141 ImeTracker              dev.hotwire.turbo.demo               I  dev.hotwire.turbo.demo:d0f1ad: onRequestHide at ORIGIN_CLIENT_HIDE_SOFT_INPUT reason HIDE_SOFT_INPUT
2024-03-27 13:50:28.565 18141-18141 StradaLog               dev.hotwire.turbo.demo               D  bridgeDestinationDidStop .......... [https://506f8e14c2c2.ngrok.app]
2024-03-27 13:50:28.565 18141-18141 TurboLog                dev.hotwire.turbo.demo               D  fragment.onStop ................... [session: main, location: https://506f8e14c2c2.ngrok.app, fragment: WebHomeFragment]
2024-03-27 13:50:28.583 18141-18141 TurboLog                dev.hotwire.turbo.demo               D  fragment.onViewCreated ............ [session: main, location: https://506f8e14c2c2.ngrok.app/follow-external-redirect, fragment: WebFragment]
2024-03-27 13:50:28.588 18141-18141 TurboLog                dev.hotwire.turbo.demo               D  fragment.onStart .................. [session: main, location: https://506f8e14c2c2.ngrok.app/follow-external-redirect, fragment: WebFragment]
2024-03-27 13:50:28.590 18141-18141 StradaLog               dev.hotwire.turbo.demo               D  bridgeDestinationDidStart ......... [https://506f8e14c2c2.ngrok.app/follow-external-redirect]
2024-03-27 13:50:28.610 18141-18141 TurboLog                dev.hotwire.turbo.demo               D  visitLocation ..................... [session: main, location: https://506f8e14c2c2.ngrok.app/follow-external-redirect, options: TurboVisitOptions(action=ADVANCE, snapshotHTML=null, response=null), restorationIdentifier: ]
2024-03-27 13:50:28.647 18141-18380 TurboLog                dev.hotwire.turbo.demo               D  visitStarted ...................... [session: main, location: https://506f8e14c2c2.ngrok.app/follow-external-redirect, visitIdentifier: 094d240b-cbb3-459c-9c78-73bd5400bb5b, visitHasCachedSnapshot: false, visitIsPageRefresh: false]
2024-03-27 13:50:28.650 18141-18380 TurboLog                dev.hotwire.turbo.demo               D  visitRequestStarted ............... [session: main, visitIdentifier: 094d240b-cbb3-459c-9c78-73bd5400bb5b]
2024-03-27 13:50:28.741 18141-18141 StradaLog               dev.hotwire.turbo.demo               D  bridgeDestinationDidDestroy ....... [https://506f8e14c2c2.ngrok.app]
2024-03-27 13:50:28.811 18141-18141 chromium                dev.hotwire.turbo.demo               I  [INFO:CONSOLE(0)] "Access to fetch at 'https://turbo.hotwired.dev/' (redirected from 'https://506f8e14c2c2.ngrok.app/follow-external-redirect') from origin 'https://506f8e14c2c2.ngrok.app' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.", source: https://506f8e14c2c2.ngrok.app/follow-external-redirect (0)
2024-03-27 13:50:28.811 18141-18380 TurboLog                dev.hotwire.turbo.demo               D  visitRequestFailedWithStatusCode .. [session: main, visitIdentifier: 094d240b-cbb3-459c-9c78-73bd5400bb5b, visitHasCachedSnapshot: false, error: UnknownError(statusCode=0, reasonPhrase=null)]
2024-03-27 13:50:28.815 18141-18141 Compatibil...geReporter dev.hotwire.turbo.demo               D  Compat change id reported: 210923482; UID 10191; state: ENABLED
2024-03-27 13:50:28.841 18141-18380 TurboLog                dev.hotwire.turbo.demo               D  visitRequestFinished .............. [session: main, visitIdentifier: 094d240b-cbb3-459c-9c78-73bd5400bb5b]

@hjhart
Copy link
Author

hjhart commented Mar 27, 2024

@jayohms I'm happy to take this work on, as it is blocking my companies critical path, but do you have any pointers as to what code I might want to touch before I dive into this work?

@jayohms
Copy link
Collaborator

jayohms commented Mar 28, 2024

@hjhart I dug into this and it's is an issue in both turbo-android and turbo-ios, so we'll need fixes in both libraries. See the PR with details: #325

Due to the CORS policy in turbo.js fetch requests, all the adapters see external redirects as request failures, but the linked PR handles the issue in a similar but different way than the default browser adapter. Can you give it a try and see if it resolves your issue?

@hjhart
Copy link
Author

hjhart commented Mar 28, 2024

@jayohms, wow, that works perfectly. Thanks so much!

Screen.Recording.2024-03-28.at.9.14.22.AM.mov

@jayohms
Copy link
Collaborator

jayohms commented Mar 28, 2024

The fix is now available in 7.1.2: https://github.com/hotwired/turbo-android/releases/tag/7.1.2

@hjhart
Copy link
Author

hjhart commented Apr 2, 2024

Hey @jayohms, thanks for the quick release! Does this also require an upgrade of turbo.js, or turbo-rails?

@hjhart
Copy link
Author

hjhart commented Apr 3, 2024

Edit: Opened up another issue #327

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

3 participants