Orbit
Orbit

Reputation: 2385

Redirect in Chrome Custom tab is not captured for deep link

I'd like to capture a redirect that occurs in a Chrome Custom tab to ensure the user stays in a native mobile application.

Here's how the Chrome Custom Tab is launched:

val url = "https://demo.company.com/sso/oidc/start/?idp_connection_id=Username-Password-Authentication&status_response_url=https://member.example.com/urgent"
val builder = CustomTabsIntent.Builder()                                                                                                                                         
val customTabsIntent = builder.build()                                                                                                                                           
customTabsIntent.launchUrl(this, Uri.parse(url))

That web page redirects to the URL given as the status_response_url parameter after the user authenticates. The mobile app registers for the appropriate scheme:

 <intent-filter android:autoVerify="true">
     <action android:name="android.intent.action.VIEW" />
     <category android:name="android.intent.category.DEFAULT" />
     <category android:name="android.intent.category.BROWSABLE" />
     <data
         android:host="member.example.com"
         android:scheme="https" />
  </intent-filter>

Unfortunately, the system does not seem to capture the redirect. Why?

Upvotes: 13

Views: 8475

Answers (3)

luckyhandler
luckyhandler

Reputation: 11329

My problem was that chrome didn't redirect into the app after payment inside a custom chrome tab. Thanks to @GaryArcher I realized what the issue could be but solved it differently.

No user action is necessary as I created a custom endpoint (cloud function in my case) and referenced this as redirect url (status_response_url in your case). Inside this function I redirect to whatever url I like and correctly jump into the app.

Example:

export const resultRedirect = functions
  .https
  .onRequest(async (req, res) => {
    const paramOne = req.query.paramOne as string;
    const paramTwo = req.query.paramTwo as string;

    res.redirect(`de.company.app://paymentResult?paramOne=${paramOne}&paramTwo=${paramTwo}`);
  });

Upvotes: 0

Stanislav Berkov
Stanislav Berkov

Reputation: 6287

@Gary Archer describes that is it well known problem with App Links and SSO.

I want to add that in AppAuth example (that works ok) https://github.com/openid/AppAuth-Android/blob/c6137b7db306d9c097c0d5763f3fb944cd0122d2/app/java/net/openid/appauthdemo/LoginActivity.java#L464 they have warmUpBrowser function to workaround this problem. If you create browser intent in "Login" button handler then redirect in chrome tabs will not be captured (since browser receives no interaction). That is why they create browser intent in advance, as a result some interaction captured and redirect received in intent.

It took me several days to understand why they do so.

Upvotes: 0

Gary Archer
Gary Archer

Reputation: 29243

This is a well known problem with App Links and SSO, due to the lack of a user gesture.

You are using the preferred Claimed HTTPS Schemes option but an interstitial web page is needed for it to work reliably.

My blog post has further info on this, including a code sample you can run to review the UX.

Upvotes: 6

Related Questions