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

Only allow permissions.request() during user interaction #77

Closed
mnoorenberghe opened this issue Apr 12, 2016 · 32 comments
Closed

Only allow permissions.request() during user interaction #77

mnoorenberghe opened this issue Apr 12, 2016 · 32 comments

Comments

@mnoorenberghe
Copy link
Member

Some quotes from Google:

We believe users should only see a permission prompt if they’ve demonstrated willingness to grant that permission, or at minimum, intent to use a feature which requires that permission. In particular, we strongly advise against triggering permissions prompts on page load.

Showing users permission prompts they aren’t interested in is distracting and spammy. To ensure Chrome users get the best experience on the web we’re exploring automatically denying permission prompts from sites that display prompts which users largely ignore or deny (or worse, revoke).

from https://docs.google.com/document/d/1WNPIS_2F0eyDm5SS2E6LZ_75tk6XtBSnR1xNjWJ_DPE/edit#heading=h.55stxhevs7pi

Always request access to location on a user gesture

from https://developers.google.com/web/fundamentals/native-hardware/user-location/user-consent

This new API seems like the perfect opportunity to enforce this restriction to avoid spammy popups: Permission requests shouldn't appear if permissions.request() isn't called as a result of user interaction. The older permission APIs can eventually be deprecated in favour of .request().

@mounirlamouri
Copy link
Member

Note that the location request requiring a user gesture isn't actually true.

However, I agree that we should probably be requesting a user gesture. This has been in my TODO list for a while but my concern is that websites might use other means to request a permission than the Permissions API if we add restrictions compared to existing APIs (for example, Notifications.requestPermission() or navigator.geolocation.getCurrentPosition(function(){})). This said, it might be a good thing to do to enforce good practices and if new APIs use the Permissions API for request, they will force websites to use this pattern.

@adrifelt @annevk WDYT?

@adrifelt
Copy link

How we define "user interaction" has always been a sticking point in the past. I would be in favor of this as long as we get a solid definition of "user interaction."

@mnoorenberghe
Copy link
Member Author

I think allowed to show a popup is the most common definition.

@jyasskin
Copy link
Member

And it's what I've used for Web Bluetooth. We've had some complaints, but most have been because Chrome doesn't propagate user gestures through Promise.then, which is just a bug.

@adrifelt
Copy link

I was under the impression that various odd things are treated as user gestures, like hitting "Esc."
cc @kjayc

@jyasskin
Copy link
Member

If the things browsers treat as user gestures don't match https://html.spec.whatwg.org/multipage/browsers.html#allowed-to-show-a-popup, we should get HTML updated. It's also possible we should split "allowed to show a popup" into different terms that cover popup windows vs these permissiony popups. We should probably do both of those separately from deciding whether permissions.request() should insist on a user gesture.

@mounirlamouri
Copy link
Member

@adrifelt what would you call a user interaction? FWIW, I don't think we should stick with "show a popup" it's an old concept that was meant for anti-spam. Different features might have different rationale.

@annevk
Copy link
Member

annevk commented Apr 13, 2016

It was meant to make sure the user requested it and not the page. It maybe should be renamed though. It is however what various specifications have been adopting and what I think is the fundamental concept in implementations. E.g., the fullscreen API uses it too.

One problem with "allowed to shop a popup" is touch events, but it's unclear how to solve it for those as I understand it.

@raymeskhoury
Copy link
Collaborator

It seems like the definition doesn't count plain keyboard events, only clicks and form change events. Is that right? I guess that would avoid counting 'esc' which seems good (and possibly part of the motivation). Still, it seems like we do allow esc to trigger a popup in Chrome: http://jsfiddle.net/Ltyqd05m/5/ Not in FF though :)

To me it seems like the requirements for popups vs permissions are going to be similar, but if there were good reasons to have a different definition that seems ok too.

@mounirlamouri
Copy link
Member

@annevk for example, we want Fullscreen to be triggered by other things like orientation change. We are still exploring this but if it happens, it would no longer fully follow the "pop up" rules. Also, it seems that there are two types of user gesture requirements: security and spam. For some, we might be more relaxed than others. Furthermore, Blink is looking into changing user interaction to no longer accept touch events apart from clicks.

In short, I don't think we should ignore the "allowed to show a popup" rules but we should allow ourselves to think freely outside of this box.

@annevk
Copy link
Member

annevk commented Apr 14, 2016

No disagreement there. I just disagreed with the characterization that it's old. It's still very much alive and important.

@TanviHacks
Copy link

Regardless of how we exactly define user gesture, does anyone disagree that Permission Prompts should require user gesture? Are there any permissions for which this requirement doesn't make sense (ex: push notifications)?

@martinthomson
Copy link
Member

@TanviHacks, I think that push depends a great deal on how you intend to trigger the prompt. Most uses that I've seen have a button that says "Enable Notifications". That works.

@jyasskin
Copy link
Member

I'm seeing consensus that we should require a user gesture in permissions.request(). Whether we should have request() at all is more contentious, but if it exists, it should require the gesture. I'm going to wait to add the requirement until we've got the overall model figured out, but then I'll send a PR.

@jan-ivar
Copy link
Member

jan-ivar commented Jun 1, 2016

@TanviHacks, @mnoorenberghe Is your proposal to allow requests during page load only if persistent permissions have been granted?

If yes, this seems biased toward the Chrome model where repeat visitors are (effectively) persistent permission visitors.

Example (today): Alice chats: "Hi Frank and Charlie, lets meet again at https://appear.in/alice"

  • Charlie uses Chrome, so his page loads right up and the call is on.
  • Frank uses Firefox, so Firefox asks him to share his camera. He agrees, and the call is on.

With your proposal, Charlie is unaffected, but Frank is now two clicks behind instead of one:

  • Frank uses Firefox, so he has to click a button for Firefox to ask him to share his camera. He agrees, and the call is on.

This seems undesirable.

@mnoorenberghe
Copy link
Member Author

Both Firefox and Chrome allow persistent WebRTC permissions IIUC and with the upcoming Firefox UI persistence will be more discoverable with a checkbox instead of being buried in the split menu dropdown. It sounds like you're saying Chrome will automatically persist a permission decision without explicit opt-in by the user? Do you have documentation for how that works? That seems like an enhancement Firefox could add, not necessarily a blocker for a spec change to prevent unsolicited prompts.

@jan-ivar
Copy link
Member

jan-ivar commented Jun 1, 2016

@mnoorenberghe Your proposal seems to hinge on the lack of non-persistent permission, so it hardly matters where the checkboxes are.

It sounds like you're saying Chrome will automatically persist a permission decision without explicit opt-in by the user?

Yes, try it here.

Do you have documentation for how that works?

No.

That seems like an enhancement Firefox could add, not necessarily a blocker for a spec change to prevent unsolicited prompts.

If your proposal depends on Mozilla switching to Chrome's permission model, then I'd say it's a blocker.

@jyasskin
Copy link
Member

jyasskin commented Jun 1, 2016

If a Chrome user grants a permission, it's assumed they want to persist that grant across page reloads, and the only way to make the grant not hold on the next load is to explicitly revoke it.

I understand the proposal as "a page can't cause a permission prompt without a user gesture." If the user has granted persistent access to one camera, the page would be able to start using that camera on page load. It would not be able to request access to another one on page load.

If a user intended to grant permission temporarily, it seems like we should be discouraging pages from bugging them about it until they express interest in re-granting the permission. The premise in Frank's scenario is that he intends to give appear.in access to his camera every time he visits, but he's somehow failed to do it and so is getting bugged each time he visits. Why isn't the right thing for him to do just to grant persistent access?

We could add an extra bit to the permissions that get stored: if the user has ever granted this site permission before, then a new request doesn't require a gesture. If it's the first time, it does require a gesture.

@jan-ivar
Copy link
Member

jan-ivar commented Jun 2, 2016

@jyasskin I'm fairly sure Chrome's persistent grants are collateral, not per device, FYI.

If a user intended to grant permission temporarily, it seems like we should be discouraging pages from bugging them about it until they express interest in re-granting the permission.

Nah. If appear.in bothers Frank, he picks "Never Share". Problem solved.

Even for the drive-by web, this is a non-issue in Firefox today, because its door-hangers minimize when ignored, so they're not the nuisance they are in Chrome. Let Chrome fix its UX without requiring spec changes.

Why isn't the right thing for him to do just to grant persistent access?

Because he prefers control over when the camera turns on.

Please read the spec: "Authorization may be given on a case-by-case basis, or be persistent."

@jyasskin
Copy link
Member

jyasskin commented Jun 2, 2016

Are you worried at all about click-jacking? If the page can control when the door-hanger appears, it can show it as the user's about to click where 'accept' will be located?

@jan-ivar
Copy link
Member

jan-ivar commented Jun 2, 2016

@jyasskin Another UX problem. To paraphrase @martinthomson, UX is not the domain of specs. We allow browsers sovereignty over choices regarding permissions and how they are managed.

@raymeskhoury
Copy link
Collaborator

@jan-ivar is your stance that we shouldn't require user gestures at all? Or that we should always require a user gesture, even if a prompt will not be shown? Or neither? It's a bit unclear from this discussion :)

@jan-ivar
Copy link
Member

jan-ivar commented Jun 3, 2016

@raymeskhoury My stance is that permission is between a User Agent and its user. If user agents are bothering their users, then that’s on them.

Chrome's permission UX used to be easier to ignore, but recently became more intrusive, shifting power away from users, and toward sites. “User gestures" seems like a wallpaper reaction to that shift.

I think it’s fine for Google to explore these UA choices, but their findings are going to fit their model, not every browser’s model. When we're suggesting all browsers adopt Chrome’s permission model, then we should know we are off track.

Permission prompts are not content pop-ups, they are the browser’s own communication with their user. Specs have traditionally no business here, nor does content (which is why I also support #83).

@jyasskin
Copy link
Member

jyasskin commented Jun 3, 2016

@jan-ivar That's an explanation of why you're opposing this proposal, but you didn't answer @raymeskhoury's question. I'm pretty sure you're arguing that specs should not require a user gesture on operations that may show a permission prompt.

If requiring a gesture were really a pure UX issue, I think we'd conclude that UAs "may" require a gesture, since everything else in UX is a "may". Is that the conclusion you want?

I've pinged public-webappsec to pull in more opinions: https://lists.w3.org/Archives/Public/public-webappsec/2016Jun/0008.html. Just to be clear, nobody wants to suggest that all browsers adopt Chrome's permission model. We're trying to find the requirements that work best for all reasonable permission models, and when we make suggestions that happen to privilege the browser we work on, it's good to have that pointed out so we can correct it.

@jan-ivar
Copy link
Member

jan-ivar commented Jun 3, 2016

@jyasskin Thanks, yes, "may" seems fine. I'm not hearing anyone seriously proposing to require user gestures when persistent permissions are granted.

If anyone wants to propose a way to prevent (or limit the impact of) t-mobile geo-spamming their users on page-load that respects the appear.in use-case I care about, then I'm willing to take a look.

But UAs have a lot of leeway already in whether they ever respond to a site's request, reject on the user's behalf, or how intrusively they bother their user. They're also invested in their users having a pleasurable experience, so the best we can do may be to leave them alone on this one.

@benfredwells
Copy link

I'm much more comfortable having this be 'may' instead of 'must', for a couple of reasons:

  • I haven't seen any clear data to say that even with Chrome's UX, prompts from gestures have better response rates. It's intuitive that this would be the case but there isn't any actual data yet. I'm working on the necessary reporting in Chrome to get this data.
  • If we want to enforce gesture I think we should do this no matter which API is used. E.g. if we think geolocation prompts should require gestures, we should ensure this is the case regardless of which API is used. This might be hard (i.e. necessitate changing existing APIs) but it is preferable to having one API enforce it and another not.

@noncombatant
Copy link
Collaborator

noncombatant commented Jun 10, 2016

@jan-ivar says:

"""Example (today): Alice chats: "Hi Frank and Charlie, lets meet again at https://appear.in/alice"

Charlie uses Chrome, so his page loads right up and the call is on.
Frank uses Firefox, so Firefox asks him to share his camera. He agrees, and the call is on.
With your proposal, Charlie is unaffected, but Frank is now two clicks behind instead of one:

Frank uses Firefox, so he has to click a button for Firefox to ask him to share his camera. He agrees, and the call is on.
This seems undesirable."""

My goal is for the permission grant to be a seamless part of the workflow. Ideally, both Frank and Charlie would get an HTML page like:

Welcome to Video Conference Example App Dot Com!
[ Join Call with Alice ]

Clicking on the [ Join Call with Alice ] button is a gesture, and the onclick event handler is thus now empowered to do such things as call getUserMedia. A nice UA could then fulfill the getUserMedia call in its own way, e.g.

  • Returning a descriptor to the device's 1 camera
  • Showing a chooser to choose between the several cameras (say, front and back)
  • Returning a descriptor to the device's front camera, but making it easy for the person to switch to the back camera (e.g. by detecting device rotation, showing a Switch Camera button in a semi-transparent overlay, or whatever else)

I really don't see automatic, gesture-less camera/mic enablement onload as a good idea, as a default experience.

Unless, and I've said this before in other fora, the UX offers a chooser like:

Select a camera and mic:
  __ Front Camera + Mic __
  Rear Camera + Mic
  Mic Only

[ Cancel ]    [[ Join Call ]]

   [x] Always use this choice with calls.example.com

If the person checks that Always Use checkbox, then I think that's a reasonable signal that the person wants to auto-join all calls on that site with the selected media input devices. However, a well-behaved calls.example.com app will not abuse that power, such as by auto-joining without an extremely clear indicator that the person intends to. (Such as navigating to a 1-time capability URL, having set a preference in the site's own UX, et c.)

@martinthomson
Copy link
Member

@noncombatant, that is a fine ideal. I also don't like seeing stuff like this happen on load. If a page wants to have its "Call Alice" button also navigate can detect (using this wonderful permissions API) if it can grab a camera on load and do that if that makes sense.

I wonder, do we treat same-origin navigation as implying that a popup is permitted?

Note that your "Mic Only" option is expressly forbidden by the gUM spec, but that's inconsequential.

@jan-ivar
Copy link
Member

Ideally, both Frank and Charlie would get an HTML page like:

@noncombatant You're missing the key difference: Charlie suffers this inconvenience once, Frank every time.

You're also missing that Frank is not Charlie. His only problem isn't that he can't find the "Always allow" button. Frank actually doesn't want to trust this site with persistent permission, thus he represents a true choice, not just the user of another browser. This is the default in Firefox.

Clearly, automatic, gesture-less camera/mic enablement onload is desirable for a good user experience, as no-one is proposing imposing a user gesture when persistent permissions are granted.

@noncombatant
Copy link
Collaborator

noncombatant commented Jun 13, 2016

@jan-ivar: I am afraid I don't understand what you're saying. I haven't finished my coffee yet, so it could be that. :) But you seem to want to not grant persistent permissions to origins, but also to have a frictionless permission-granted-onload experience. To me, a frictionless permission-granted-onload experience is very similar to a persistent permission grant. The reason I think that is because I consider clicking a link (e.g. the capability URL to start a video chat session) to be a very weak signal of intent — so weak that I am not sure it is a signal at all. (At least, not a signal for such a powerful action as turning on the camera. Perhaps it is signal enough for other things.)

In any case, it seems to me that different browsers implementing the same API, compliant with the specs but with different UX workflows is possible, and desirable, and is a key differentiator for browsers. Especially in such a new area — I don't think any of us is 100% certain that one workflow or another is the best, and it seems to me like it's a good thing for us all to try various things. I also suspect that one size does not fit all; different people have different expectations, and that is OK.

@jan-ivar
Copy link
Member

@noncombatant I want less-trusting users to have the option of a frictionless one-click permission-requested-onload experience, because why not?

jyasskin added a commit to jyasskin/permissions that referenced this issue Jul 15, 2016
This allows a UA to leave the permission state at "prompt" but deny
permission requests that weren't triggered from a user gesture without
prompting the user. We don't require UAs to deny these prompts because
it would cause non-persistent permissions to require two click in
some flows that Firefox folks think should only require one click.

Fixes w3c#77.
jyasskin added a commit to jyasskin/permissions that referenced this issue Aug 5, 2016
This allows a UA to leave the permission state at "prompt" but deny
permission requests that weren't triggered from a user gesture without
prompting the user. We don't require UAs to deny these prompts because
it would cause non-persistent permissions to require two click in
some flows that Firefox folks think should only require one click.

Fixes w3c#77.
jyasskin added a commit to jyasskin/permissions that referenced this issue Aug 26, 2016
This allows a UA to leave the permission state at "prompt" but deny
permission requests that weren't triggered from a user gesture without
prompting the user. We don't require UAs to deny these prompts because
it would cause non-persistent permissions to require two click in
some flows that Firefox folks think should only require one click.

Fixes w3c#77.
@marcoscaceres
Copy link
Member

Closing per #83.

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

Successfully merging a pull request may close this issue.