Development
Solving Android Login Issues with Chrome Custom Tabs
When Android developers need to display a web page in their apps, most folks tend to opt for WebViews. But I recently came across a situation in a hybrid mobile app that required Chrome Custom Tabs (CCTs) instead, specifically for Android login flows.
The problem? The CCT was sharing session cookies with the Chrome browser, and these cookies weren’t cleared on logout. This meant users were being logged back in unexpectedly—not a great user experience.
While CCTs aren’t new, I hadn’t had a good reason to check them out before facing this particular challenge. So with my curiosity piqued, I jumped in to learn more about what CCTs are, what they’re good for, and how they could help solve this login screen problem.
Enter Stage Left: Chrome Custom Tabs
CCTs are a feature within the Chrome browser on Android that enable customized mobile browsing experiences. They’re available on any Android phone where Google Play Services is installed, and they can be identified by their distinctive toolbar at the top of the screen.
CCT in Dark Mode, API 33.
Some key benefits:
-
Security: CCTs leverage the installed Chrome browser’s regular updates, ensuring up-to-date security and performance improvements without additional app-level updates. And unlike WebViews, CCTs come with off-the-shelf integration with Chrome Password Manager, meaning things like login autofill works seamlessly and without additional setup or restrictions.
-
Performance: CCTs have a pre-warming mechanism and share resources with the Chrome browser to speed up webpage performance, so they’re a great fit for “feed-style“ screens (e.g. news, subreddits, chat, etc).
-
User experience: Unlike WebViews, which are embedded directly in XML layouts or constructed in code, CCTs are launched using an Intent, opening a dedicated, lightweight browser Activity that acts as a host container for the component, powered by Chrome. This approach provides users with a seamless browsing experience, allowing them to navigate smoothly between your app and web content without losing context or feeling disconnected.
-
Backward compatibility: Because CCTs rely on the Chrome browser’s rendering engine, they’re less susceptible to Android WebView API fragmentation issues.
Solving Problems with CCTs
Turning back to the issue of the logout problem described earlier, a WebView-based solution was disqualified right off the bat since the app needed to display a CCT-based login screen for… reasons™️. With that hard constraint in mind, we looked into other ways of clearing shared session cookies, including CCT custom HTTP Headers and Incognito Mode. But it was a combination of three key adjustments to the Redirect URI that did the trick:
Sometimes, the best way backward is a redirect forward.
- Send a new REST API request from the web app to clear session cookies (i.e.
GET /sso/saml
in the diagram). - Have the Native Android side intercept this new request by adding an
<intent-filter>
to the Manifest, with scheme, host and optional path set to listen for the new Redirect URI (ie.rzplnecct://logout
). - Add logic to open the Login CCT programmatically, and verify the new Redirect URI and associated API call.
In practice, because the session cookies are cleared by the web app, the OAuth Redirect URI isn’t sent as it was before, meaning users aren’t logged back in automatically after logout. Success!
Disclaimers
While CCTs are a great tool in certain circumstances, here are three trade offs to keep in mind when considering them for your projects:
Visual Styling
Like a stubbornly bright accent wall in an otherwise dim and cozy room, CCTs tend to stand out. Fortunately, Google offers a way to mitigate this, at least partially—a set of APIs are available for making some basic CCT style and UI changes, including: toolbar colour, entry/exit animations, a custom close icon, toolbar auto-hiding, and some custom toolbar actions. While not perfect, these APIs can help keep CCTs better aligned with an app’s overall visual design.
CCT with a themed toolbar, API 31.
Closing CCTs Programmatically
There’s no direct or easy way to close a CCT programmatically. The reason for this has more to do with how Activities work in Android than with CCTs themselves. But having said that, to close a CCT, Intent flags need to be added to manage the Android Activity stack:
How to “close the door” when leaving a CCT.
- Set
android:launchMode="singleTop"
in your Activity’s Manifest entry. This ensures the original Activity instance remains. - Launch an intermediate Activity (
New Activity
) withFLAG_ACTIVITY_NO_HISTORY
. This ensures it’s removed from the stack once closed. - When
New Activity
finishes, start the client Activity with these Intent flags to clearCustom Tab
Activity from the stack:FLAG_ACTIVITY_CLEAR_TOP
— removes any intervening activities above the targetFLAG_ACTIVITY_SINGLE_TOP
— ensures the existing Activity instance is reused
- Handle cleanup in the original Activity’s
onNewIntent()
method.
Custom Headers and Security
One more important quirk to be aware of is how CCTs pass custom HTTP headers. CCTs take a more secure approach than WebViews by checking for a pre-registered Digital Asset Link (a “signature” in the form of a JSON file) that’s used to prove app and domain ownership. This implies that custom HTTP headers can only be used on websites owned by an app’s author. While this boosts security, it can get cumbersome in scenarios like white-label apps.
Final Thoughts
Once I got a handle on their quirks, I was pleasantly surprised by how easily CCTs integrate into complex workflows. Whether you want to verify requester trust, leverage Chrome security features, or embed web content smoothly, CCTs offer valuable advantages alongside traditional WebViews—no need to choose one vs the other since both can happily coexist in the same project.
If you’re considering adding CCTs to your app—or if you’d like a hand getting started—we’d love to help out. Drop us a line!
Previous Post
You Are Here: How Teams Make Product Decisions
Mar 14th, 2025 | Nick Wilkinson • Development
More on the theme of Development
You Are Here: How Teams Make Product Decisions
Mar 14th, 2025 | Nick Wilkinson • Development
Assembling The Feedback Wizard
Dec 20th, 2023 | Jenn Cooper • Development
Walk the Line: iOS Account Deletion
Dec 14th, 2022 | Nick Wilkinson • Development
Follow for more updates from Steamclock.
Archive (65) RSS Feed @steamclock