-
Notifications
You must be signed in to change notification settings - Fork 13
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
Allow installHandler to include a url to open after success #33
Comments
To consider this, we need to model (write down) how we would expect this to work for all major browsers and the different (1p vs. 3p) modes we have to support. It's important to understand what popup windows would be opened when and where "transient user activations" will be consumed. Browsers generally gate various APIs on such a user interaction and "consume" the activation for each API call, meaning you need one user activation per call. In 3p-mode browsers, calling In 1p-mode browsers, calling There are probably more details here to work through to determine the viability of this feature. |
Ok, thanks for the great explanation. Can you clarify for me what 1st vs 3rd person mode means in this context? I think I've seen 2 different interaction patterns when I tested using an app's in app browser, is that 3rd? |
So 1p means "first party" and 3p means "third party". Here, first party refers to the origin that a user directly visits via the URL bar and third party refers to an origin the user may interact with via embeds (usually an iframe) in the first party website. Browsers will implement or expose a number of features very differently depending on which of these contexts the user is interacting. For example, in order to prevent cross-site tracking, a number of browsers will "partition" local storage (including storage APIs for That means that if you visit site A and interact with an iframe that loads site B, the Web application loaded from B will "see" a storage bucket for the combined sites A+B. You can think of this as a sort of double-key'd Map. If the application writes something to local storage in this scenario, like a cookie or using an API like If the user visits site B directly (e.g., by typing its origin into the URL bar), the written value will not be present when an attempt is made to try and read it. The same is true in reverse -- values written by a Web application on site B in a "first party context" will go into a different storage bucket and not be seen when visiting site B via an iframe on site A. This approach prevents some unwanted tracking behavior by, for example, ensuring that if there's a tracker loaded into an iframe on site A (potentially even invisibly), it cannot create a value that can then be read back on some other site, let's say C, if it embeds an iframe for the same tracker origin. This is what it means to have "partitioned storage" -- every different scenario (site B on site A, site B directly, site B on site C, so on) gets a different storage bucket. Some browsers, like Brave, have partitioned storage like this -- and -- it's ephemeral. So it gets destroyed quite frequently, perhaps even when you just leave the site (this is up to the manufacturer's policy which can change at any time). Other browsers persist partitioned storage, but perhaps only for a short period of time. Some browsers, like Chrome, do not have partitioned storage and use the same storage bucket everywhere. This can also be controlled by settings -- and the defaults for Chromium-based browsers may differ based on the OS you're using. Chrome (and Chromium generally) are trying to be able to change their default everywhere to use partitioned storage, but can't do so yet without breaking a lot of valid use cases (i.e., not unwanted tracking) on the Web. Storage Access APIAdditionally, some browsers implement the "Storage Access API" -- to try and help enable use cases where a user actually wants some service to keep track of things for them. This API allows, so long as the user interacts with an iframe on a page, the 3rd party Web application running in that iframe to request to use the 1st party storage bucket. The user may or may not be prompted by a browser-rendered dialog when this happens ... depending on whether you're using, for example, Firefox or Safari. Whether or not they render that dialog can be based on whatever the browser manufacturers feel is the best policy, and it's open to change at any time. Some browsers, like Safari, will require the user to have visited whatever site is rendered in an iframe in a first party context before using the iframe. It also requires that the Web application at that time have received transient user interaction coupled with writing a cookie to the 1p storage bucket -- before the Storage Access API can ever be called successfully in a 3p context (iframe) later. Additionally, the storage access and persistence is highly constrained, limiting the storage of cookies to only seven days, if they have been set by JavaScript as opposed to the server. This is problematic for applications (such as the CHAPI polyfill mediator!) that are only intended to do everything on the client. Furthermore, Safari does not provide shared storage access to anything other than cookies, so Some browsers, like Brave, have partitioned storage -- but do not implement the Storage Access API and currently say they do not plan to. In other words -- all of this gets really complex :). Something to note about using the Storage Access API in the context of CHAPI -- we need user activation for both the CHAPI mediator polyfill (to access the registered credential handlers) and then we'll almost always need it again at the credential handler (digital wallet) provider site -- so the digital wallet can access local storage. That is messy on its own, but asking the user to click even more times to open popup windows to visit the mediator site in a 1p context ... and then asking them to click again to interact with it to store a cookie is just not workable. This can even get worse if you just need to check whether you've got storage access (to the 1p bucket) in the first place. So, we've found that for the use case we have with the credential handler mediator polyfill, the Safari implementation of the Storage Access API is essentially unworkable. The whole point of the mediator polyfill is to invisibly store the credential handler registrations that the user wants stored -- without putting some "special mediator storage site" in their face or requiring them to visit it on their own. We also don't want any cookies going anywhere if we can avoid it -- all storage should be local. Given this problem and other complexities we encountered when we tried to make the Storage Access API work in the past, we've opted to just use 1p windows on browsers with partitioned storage. In short, that means creating popup windows so that the user is visiting a window in a 1p context (with the origin in the URL bar), as opposed to using an embedded iframe in the site they were on. You'll notice that if you use CHAPI in Chrome, you'll get a more integrated and better UX on desktop than if you use CHAPI in another browser -- because that other browser will generate popup windows to ensure that the same storage bucket (always the 1p one) is used. On mobile, the problem is less evident because popups fit more seamlessly into the UX on a small screen where only one window is ever shown. Getting all of the above to work properly -- and switch properly -- across different browsers is quite challenging. Additionally, there are other complexities around message passing and performance that we have to deal with. This means that we actually always use iframes that minimally load the mediator site (authn.io) on relying party websites. This iframe is always present so when a call is made to CHAPI, we can quickly receive it and decide whether to open an additional 1p window (or not) to process the request. Otherwise, there would be a (user experienced) delay in loading the authn.io mediator site when the API was called. EDIT: I should note that some have said that using the terms 1p and 3p are problematic (and they are right) and more specific references should be made in specs (I agree), but they are so ingrained and simple to use when discussing common problems and how browsers work that it may be a while before some different or more precise language is adopted in conversation. |
This is a very good explanation and I appreciate you spending the time to educate. It definitely shows how this gets complex when supporting multiple browsers while also creating a seemless user experience. Thanks! |
Hi @dlongley, thank you for writing up your challenges with the Storage Access API. Trying to summarize the main challenges:
I think it would be great if there could be support through FedCM as outlined in w3c-fedid/FedCM#374 but I'd still be interested in these challenges with SAA (I think they also have implications on the utility for FedCM). |
Thanks for your response!
Well, when attempting to make this work with Safari, we end up needing more than just two user interactions. You may be referring to a specific API interaction, e.g., whether a call to SAA to check for current storage access followed by one to request it may not consume a user gesture / activation -- or something along those lines. I don't know where the behavior is with the SAA these days, but to give some historical background, we've had the CHAPI polyfill for something like seven years now -- and have adapted it over time to whatever browser primitives offer the best UX. This includes implementing several different variants against the SAA over the past two years or so. I'm sure a number of things have changed with how user interactions are consumed (or are not) in that time period, but the totality of what the user must go through still certainly requires more than two on Safari. These challenges ultimately led us to dropping trying to use it. I detail more of that later.
TL; DR: Users directly interact with digital wallet websites, not the polyfilled "mediator website", So, if you're still reading, here's the long version: The CHAPI polyfill provides two components to enable the "Credential Handler API" to work properly. The first is provided via a JavaScript polyfill library that other sites (both relying parties and credential handler providers, aka digital wallet providers) include in their Web applications. This library polyfills the When a call is made to get or store such a credential, a message is sent, via The mediator is responsible for:
Note that this "mediator" component is never meant to be a website that the user visits directly, it is polyfilling a missing piece of the browser. The whole point is for it to function as if it provides browser-native selection menus and local storage of the user's registered digital wallets. Also note that the user registers their digital wallets by visiting the digital wallet website(s) of their choice -- not by visiting the polyfill mediator "authn.io" website. This means that, in order to use the SAA with Safari previously, the UX for registering a digital wallet was like this:
So, that's just digital wallet registration on Safari using SAA. I'm not going to detail processing a get / store request, but suffice it to say, it's similarly bad UX -- and the digital wallet UI the mediator renders may then need to jump through similar hoops for the digital wallet site to get storage access if needed. But... once it's been done once, you can get a much nicer, seamless experience when doing get / store requests like you do today with Chrome. However, I suspect most users would never get that far before thinking someone was trying to scam them in some terrible way. Now, alternatively -- we could just not use SAA and when the user needs to register a digital wallet, open a popup to Put simply, SAA was not designed for the use case we have. It was designed for embeds like Twitter, Facebook, and so on -- where users have some relationship with the embedded site. Users are not meant to have a relationship with a polyfill mediator component rendered by If you want to learn more about the CHAPI polyfill or see some animated GIFs of it in action, you can visit these sites: https://chapi.io/ |
I see, thanks for detailing this, @dlongley! I agree that this isn't great for your use case and it doesn't seem like the web platform can really seamlessly support this kind of integration post 3rd party cookies right now. Maybe we can make progress in w3c-fedid/FedCM#374 :) I'll definitely keep this as a reference of how 1p relationship/interaction can be challenging for some use cases! |
I'm not sure if this feature would be valuable to others but here is the scenario I was looking at:
A user wants to navigate from their wallet to an issuer's website that is linked within it. They do not yet have CHAPI installed so there is 2 possible strategies for the wallet to allow this.
_blank
navigation results in the browser blocking the page thinking it's a popup)I am hoping there is a way we could add to the
installHandler
method an optional page to open after success. I'm not 100% sure this would solve the issue even but if so would allow the smoother user experience of option 2The text was updated successfully, but these errors were encountered: