禁用Safari自动填充用户名和密码

问题描述 投票:44回答:15

您可能已经知道,Safari有一个讨厌的自动填充错误,它填写电子邮件,用户名和密码字段,无论您是否设置autocomplete="off"

这是一个基本形式:

<form action="/" method="post">
    <p>
        <label>E-mail</label>
        <input type="text" name="email" value="" />
    </p>
    <p>
        <label>Password</label>
        <input type="password" name="password" value="" />
    </p>
</form>

... Safari自动填充页面加载中的那些字段,就像它应该做的那样,做得好!

如果将autocomplete="off"放到字段和/或表单元素中,Safari仍会自动填充这些字段:

<form action="/" method="post" autocomplete="off">
    <p>
        <label>E-mail</label>
        <input type="text" name="email" value="" autocomplete="off" />
    </p>
    <p>
        <label>Password</label>
        <input type="password" name="password" value="" autocomplete="off" />
    </p>
</form>

即便这样也行不通:

<form action="/" method="post" autocomplete="off">
    <p>
        <label>E-mail</label>
        <input type="text" name="secretfield1" value="" autocomplete="off"/>
    </p>
    <p>
        <label>Password</label>
        <input type="password" name="secretfield2" value="" autocomplete="off" />
    </p>
</form>

...因为Safari会查找那些<label>元素,如果它们包含“电子邮件”,“密码”等单词并继续自动填充。

Aaaahhhhha!,我想,并尝试了这个:

<form action="/" method="post" autocomplete="off">
    <p>
        <label>%REPLACE_EMAIL_TITLE%</label>
        <input type="text" name="%REPLACE_EMAIL_NAME%" value="" autocomplete="off"/>
    </p>
    <p>
        <label>%REPLACE_PASSWORD_TITLE%</label>
        <input type="password" name="%REPLACE_PASSWORD_NAME%" value="" autocomplete="off" />
    </p>
</form>

...并使用JavaScript将%TAGS%替换为真实姓名。 Safari自动填充开始。无论您是否在替换上设置了10秒超时。

那么,这真的是唯一的选择吗?

<form action="/" method="post" autocomplete="off">
    <p>
        <label>That electronic postal address we all use, but can't write the title here because Safari fills this with YOUR information if you have autofill turned on</label>
        <input type="text" name="someelectronicpostaladdress" value="" autocomplete="off"/>
    </p>
    <p>
        <label>A set of characters, letters, numbers and special characters that is so secret that only you or the user you are changing it for knows, but can't write the title here because Safari sucks</label>
        <input type="password" name="setofseeecretcharacters" value="" autocomplete="off" />
    </p>
</form>

我希望不是?

更新:@skithund pointed out in TwitterSafari is getting a 4.0.3 update,提到“登录自动填充”。有谁知道这个更新是否会解决这个问题?

html security autocomplete safari autofill
15个回答
37
投票

我有同样的问题。虽然我的解决方案并不完美,但似乎有效。基本上,Safari似乎在寻找带有密码和用户名的输入字段,并且总是试图填充它。因此,我的解决方案是在Safari可以填充的当前版本之前添加一个假的用户名和密码字段。我尝试使用style="display: none;",但这不起作用。所以,最终,我只是使用style="position:absolute; top:-50px;",这隐藏了输入字段,看起来工作正常。我不想使用JavaScript,但我猜你可以用JavaScript隐藏它。

现在,Safari从未自动填写我的用户名和密码字段。


0
投票

你可以试试这个变种。这个对我有用。如果您更改一次字段值,Safari将再次更改它。如果用户在此字段中单击,则此后Safari将不会自动更改该值。

  $.browser.chrome = /chrome/.test(navigator.userAgent.toLowerCase());
        if($.browser.chrome){
            $.browser.safari = false;
        }

        var isChanged=false;

        $('#Email').change(function () {
            if ($.browser.safari && !isChanged) {
                $('#Email').val('@Model.Email');
            }
        });

        $('#Email').click(function () {
            if ( $.browser.safari && !isChanged) {
                isChanged = true;
            }
        }); var isChangePassword = false;
    $('#OldPassword').change(function () {
        if ($.browser.safari && !isChangePassword) {
            $('#OldPassword').val('');
        }
    });

    $('#OldPassword').click(function () {
        if ($.browser.safari && !isChangePassword) {
            isChangePassword= true;
        }
    });

0
投票

浏览器程序员似乎认为他们比网站编写者更了解。虽然允许用户保存密码有时很方便,但有时候存在安全风险。对于那些时间,此解决方法可能会有所帮助:

首先使用传统的文本输入,而不是“密码”类型。

Password: &nbsp <input type="text" id="fkpass" name="bxpass" class="tinp" size="20" />

然后 - 如果您愿意 - 将焦点设置为输入字段。

<BODY onLoad="fitform()">

将JS放在页面的末尾。

<script type="text/javascript">
document.entry.fkpass.focus();
function fitform() {
document.getElementById('fkpass').autocomplete = 'off';
}
</script>

现在你有一个传统的表格领域。这有什么用? 更改该输入的CSS样式,使其使用的字体全部为“项目符号”而不是字符。

<style type="text/css">
@font-face { font-family: fdot; src: url('images/dot5.ttf'); }
@font-face { font-family: idot; src: url('images/dot5.eot'); }
@font-face { font-family: wdot; src: url('images/dot5.woff'); }
@font-face { font-family: w2dot; src: url('images/dot5.woff2'); }
.tinp { font-family: fdot, idot, wdot, w2dot; color: #000; font-size:18px; }
</style>

是的,你可以'整理'代码,并添加.svg。

无论哪种方式,最终结果都与“真实”密码输入无法区分,浏览器也不会提供保存。

如果你想要字体,那就是here。它是使用CorelDraw创建的,并使用在线webfont转换实用程序进行转换。 (dot_webfont_kit.zip 19.3k)

我希望这有帮助。


0
投票

删除<form>元素。为了保持表单行为,您可以监听keypress事件以输入字段来处理按下的enter键。以防万一我也删除了input type="submit"。你可以使用button type="button"


0
投票

比使用JS清除内容更好 - 只需伪造密码字段:

<input type="text" name="user" />
<input fake_pass type="password" style="display:none"/>
<input type="password" name="pass" />

password类型加倍使浏览器处于不确定状态,因此它只自动填充用户名

fake_pass input不应该有name属性来保持$_POST干净!


0
投票

这里提到的CSS display: none解决方案对我不起作用(2016年10月)。我用JavaScript修复了这个问题。

我不介意浏览器记住密码,但想防止自动填充错误。就我而言,一个带有密码字段且没有关联用户名字段的表单。 (Drupal 7站点中的用户编辑表单,其中仅在某些操作中需要密码字段。)无论我尝试什么,Safari都会找到自动填充密码用户名的受害者字段(例如,之前可视化放置的字段)。

一旦Safari执行自动填充,我就会恢复原始值。我只在页面加载后的前2秒尝试这个。可能更低的价值也可以。我的测试显示自动填充发生在页面加载后大约250毫秒(尽管我想这个数字很大程度上取决于页面的构造和加载方式)。

这是我的JavaScript代码(使用jQuery):

// Workaround for Safari autofill of the e-mail field with the username.
// Try every 50ms during 2s to reset the e-mail to its original value.
// Prevent this reset if user might have changed the e-mail himself, by
// detecting focus on the field.
if ($('#edit-mail').length) {
  var element = $('#edit-mail');
  var original = element.attr('value');
  var interval = setInterval(function() {
    if ($(document.activeElement).is(element)) {
      stop();
    } else if (element.val() != original) {
      element.val(original);
      stop();
    }
  }, 50);
  var stop = function() {
    clearTimeout(timeout);
    clearInterval(interval);
  }
  var timeout = setTimeout(function() {
    clearInterval(interval);
  }, 2000);
}

0
投票

我在Mobile Safari 10.3.1中使用React的SPA突然遇到了同样的问题

在所有经过测试的浏览器中,我甚至不需要任何棘手的解决方法,甚至是Mobile Safari IOS 10.2

但是,由于10.3.1用户名或密码将填写在使用活动记忆选项登录后以任何形式提及“密码”,“电子邮件”,“用户名”字样的字段中。似乎使用全文搜索“分析”渲染的DOM树,然后用户代理填写数据而不考虑任何autocomplete =“off”设置。在场地的占位符文本上也会出现funnyli。因此,当您不希望在此数据无效的地方使用预先填写的用户名或密码时,您必须非常满意。

经过数小时调查的唯一解决方案是此处发布的解决方案。提供一个名为“email”的输入字段,并隐藏包含div的高度为:0px,overflow:hidden。


28
投票

浏览器忽略autocomplete=off的原因是因为有些网站试图禁用自动填写密码。

那是错的。

2014年7月,Firefox是最后一个主要的浏览器,最终实现了更改,忽略了任何试图关闭自动填充密码的网站。

关于我们的HTML表单自动完成功能的一个主要用户投诉是“它不起作用 - 我没有看到我之前输入的任何文本。”在调试此类情况时,我们通常会发现该网站已明确禁用该功能使用提供的属性,但当然,用户不知道该网站已经这样做,只是假设IE是错误的。根据我的经验,当隐藏或替换功能时,用户通常会责怪浏览器,而不是网站。

任何网站试图绕过浏览器的偏好都是错误的,这就是浏览器忽略它的原因。没有理由知道为什么网站应该尝试禁用密码保存。

  • Chrome忽略了它
  • Safari忽略了它
  • IE忽略了它
  • Firefox忽略了它

在这一点上,Web开发人员通常会抗议“但我不会在任何地方都这样做 - 只有少数才有意义!”即使这是真的,不幸的是,这是另一种情况,浏览器真的没办法分辨出来。请记住,弹出窗口曾经是网络浏览体验的一个快乐,有用的部分,直到广告商的滥用使他们成为各地用户的祸根。不可避免的是,所有浏览器都开始阻止弹出窗口,甚至打破了使用具有良好品味和自由裁量权的弹出窗口的“好”网站。

如果我是一个特殊的snowflake怎么办?

有人提出了一个很好的用例:

我有一个共享的公共区域,亭子式计算机。我们不希望有人(意外或有意)保存他们的密码,以便下一个用户可以使用它。

这并没有违反声明:

任何网站试图绕过浏览器的偏好都是错误的

那是因为在共享信息亭的情况下:

  • 它不是具有古怪政策的网络服务器
  • 它是具有奇怪策略的客户端用户代理

浏览器(共享计算机)是要求不尝试保存密码的浏览器。

防止浏览器保存密码的正确方法 是将浏览器配置为不保存密码。

由于您已锁定并控制此自助服务终端计算机:您可以控制设置。这包括保存密码的选项。

在Chrome和Internet Explorer中,您可以使用组策略(例如注册表项)配置这些选项。

来自Chrome Policy List

AutoFillEnabled

启用自动填充功能

数据类型:布尔值(REG_DWORD)

Windows注册表位置:Software \ Policies \ Chromium \ AutoFillEnabled

说明:启用Chromium的自动填充功能,并允许用户使用以前存储的信息(如地址或信用卡信息)自动填写Web表单。如果禁用此设置,用户将无法访问自动填充。如果启用此设置或未设置值,则自动填充将保持在用户的控制之下。这将允许他们配置自动填充配置文件并自行决定是否打开或关闭自动填充功能。

请将这个词告诉企业经理,试图禁用自动填写密码是错误的。浏览器故意无视任何试图这样做的人是错误的。那些人应该停止做错事。™

换句话说

换一种说法:

  • 如果用户浏览器
  • 错误“请输入您最喜欢的婚前姓名的第一个颜色的名称。”获取新密码
  • 和用户
  • 不想要他们的浏览器
  • 更新密码
  • 然后他们
  • 将点击Nope

enter image description here

  • 如果我想保存我的HIPAA密码:那是我的权利
  • 如果我想保存我的PCI密码:那是我的权利
  • 如果我想保存“用户的新密码”:这是我的权利
  • 如果我想保存一次性密码:这是我的权利
  • 如果我想保存我的“第一颜色最喜欢的少女”答案:那是我的权利。

过度统治用户的意愿不是你的工作。这是他们的浏览器;不是你的。


17
投票

修复:浏览器通过只读模式自动填充并在焦点上设置可写

 <input type="password" readonly onfocus="this.removeAttribute('readonly');"/>

(焦点=鼠标单击并通过字段标记)

更新:Mobile Safari将光标设置在字段中,但不显示虚拟键盘。 New Fix像以前一样工作,但处理虚拟键盘:

<input id="email" readonly type="email" onfocus="if (this.hasAttribute('readonly')) {
    this.removeAttribute('readonly');
    // fix for mobile safari to show virtual keyboard
    this.blur();    this.focus();  }" />

现场演示https://jsfiddle.net/danielsuess/n0scguv6/

// UpdateEnd

说明:浏览器自动将凭据填充到错误的文本字段?

好的,你刚才注意到:

Safari自动填充开始。无论[字段名称是什么] @Jari

而且有一个假设:

Safari似乎在寻找带有密码和用户名的输入字段,并且总是试图填写它@ user3172174

当有相同表格的密码字段时,有时我会注意到Chrome和Safari上的这种奇怪行为。我猜,浏览器会查找密码字段以插入您保存的凭据。然后它将用户名自动填充到最近的textlike-input字段中,该字段出现在DOM中的密码字段之前(仅因为观察而猜测)。由于浏览器是最后一个实例,您无法控制它,

有时甚至autocomplete = off也不会阻止将凭据填入错误的字段,但不会阻止用户或昵称字段填写。

上面的readonly-fix对我有用。


12
投票

将css添加到输入将隐藏safari按钮伪元素,用户将无法使用自动完成

input::-webkit-contacts-auto-fill-button, 
input::-webkit-credentials-auto-fill-button {
  visibility: hidden;
  pointer-events: none;
  position: absolute;
  right: 0;
}

7
投票

在通过Apple's Safari HTML pages扫描并且没有找到任何关于自动完成的内容之后,我做了一些搜索和思考。

在Apple讨论中阅读a (mildly) related question之后,我记得默认是不允许记住密码等(可以在iDevice系统设置中或在提示符下启用)。由于Apple已将此功能移出浏览器并进入其(专有的,i)操作系统(screen shots on this article),我相信他们完全忽略了HTML表单/字段属性。

除非他们改变他们对这个功能的心态,因为我确信这是他们预期的行为,在他们锁定的设备上,我会假设这不会消失。对于原生iOS应用程序,这可能有所不同。绝对保持表单autocomplete =“off”和hopefully they'll one day get back to the HTML5 standard为该功能。

我知道这不包括任何解决方法,但我认为如果你接受它是iDevices上的非浏览器“功能”,它是有道理的(以Apple的方式)。


5
投票

这个问题已经得到了成功的回答,但截至今天的日期,如果没有做出一些奇怪的特殊修改,这个解决方案对我没有用 - 所以如果我决定回到它那里,我会在这里注意到这一点。至于其他人的。

  • 假输入需要在dom中的真实电子邮件输入之后。
  • 假输入需要假标签。
  • 假标签不能绝对定位。
  • 无法使用显示,可见性或不透明度来隐藏虚假元素。

我找到的唯一解决方案是使用overflow: hidden剪切假元素的可见性。

<label for="user_email">Email</label>
<input autocomplete="off" type="text" value="[email protected]" name="user[email]" id="user_email">
<!-- Safari looks for email inputs and overwrites the existing value with the user's personal email. This hack catches the autofill in a hidden input. -->
<label for="fake_email" aria-hidden="true" style="height: 1px; width: 1px; overflow: hidden; clip: rect(1px, 1px, 1px, 1px)">Email</label>
<input type="text" name="fake[email]" id="fake_email" style="height: 1px; width: 1px; overflow: hidden; clip: rect(1px, 1px, 1px, 1px)" tab-index="-1" aria-hidden="true">

对于记录,此hack有用的特殊情况是管理员正在编辑其他用户的配置文件,而Safari正在用管理员的电子邮件替换用户的电子邮件。我们已经决定,对于这个Safari“功能”创建的小量(但令人沮丧)的支持请求,不值得维护一个似乎需要随着Safari收紧而发展的黑客攻击,而是为这些用户提供支持关于如何关闭自动填充。


2
投票

据报道,我不敢相信这仍是一个问题。以上解决方案对我来说不起作用,因为safari似乎知道元素何时没有显示或屏幕外,但以下对我有用:

<div style="position:absolute;height:0px; overflow:hidden; ">
  Username <input type="text" name="fake_safari_username" >
  Password <input type="password" name="fake_safari_password">
</div>

希望对某人有用!


1
投票

我的问题:我在管理区域中有一个部分允许用户设置所有语言值,其中一些包含“密码”,“电子邮件”,“电子邮件地址”等字样。我不希望填写这些值根据用户的详细信息,它们用于创建另一种语言的翻译。这是“规避浏览器偏好”的有效例外。

我的解决方案:我只是创建了替代名称:

$name = str_replace('email','em___l',$name);
$name = str_replace('password','pa___d',$name);
<input type="text" name="<?=$name?>" id="<?=$name?>" />

然后当表单发布时:

foreach($_POST as $name=>$value) {
    $name=str_replace('em___l','email',$name);
    $name=str_replace('pa___d','password',$name);
    $_POST[$name]=$value;
}

这是唯一对我有用的方法。


1
投票

我也被Safari的奇怪的默认自动完成行为所咬,但不是完全禁用它,我设法通过遵循https://www.chromium.org/developers/design-documents/form-styles-that-chromium-understands的指导方针让我工作。

具体来说,我在用户名字段中输入autocomplete="username",在密码字段中输入autocomplete="password-current"。这告诉浏览器哪些字段是自动填充的,而不是猜测它,并且它修复了我的用例的自动完成。

此方法适用于“首先发送电子邮件”登录表单(密码字段不能立即显示,例如Google登录)以及可见的用户名和密码字段的常规登录表单。

© www.soinside.com 2019 - 2024. All rights reserved.