目录
- 1.要解决的问题
- 2.一技能:原生属性,小试牛刀
- 3.二技能:傀儡input,瞒天过海
- 4.三技能:JavaScript出击,直接开大
写在前面: 如有转载,务必注明出处,否则后果自负。
1.要解决的问题
最近工作上遇到一个客户反馈的问题,说是网页上的登录界面会出现自动填充账号和密码,这会导致系统不安全,账号泄露等风险。我寻思着ntm要是没有在浏览器上点击自动保存账号和密码它会自动填充吗?真是无语。本以为不需要修改,让他自己在浏览器上清除保存密码的记录即可,没办法,打工人作为牛马有求必应。
所以,我们要解决的就是,把浏览器对input的自动填充以及填充提示给Ban掉。如下图的三个区域。
由于不同的浏览器对于自动填充有着不同的策略,所以我们需要使出各种招式组合在一起才能把它消灭,在这里我主要使用谷歌、火狐、Edge(原IE)三大浏览器来对比查看效果,一起来看看吧!
简单写了一个Demo,来模拟表单登录:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>input禁止自动填充</title>
<link rel="stylesheet" href="./index.css">
</head>
<body>
<form action="/">
<input id="userName" type="text" placeholder="请输入账号" >
<input id="userPwd" type="password" placeholder="请输入密码" >
<button type="submit">提交</button>
</form>
</body>
</html>
/* index.css */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
form {
width: 300px;
height: 200px;
margin: 100px auto;
}
input {
width: 100%;
height: 40px;
padding: 0 10px;
margin-bottom: 20px;
border: 1px solid #ccc;
border-radius: 5px;
outline: none;
}
button {
width: 100%;
height: 40px;
border: 1px solid #ccc;
border-radius: 5px;
background-color: aquamarine;
}
2.一技能:原生属性,小试牛刀
给input 添加原生属性autocomplete:
对于text框,添加 autocomplete=“off”;
对于password框,添加 autocomplete=“new-password”。
<input id="userName" type="text" placeholder="请输入账号" autocomplete="off">
<input id="userPwd" type="password" placeholder="请输入密码" autocomplete="new-password">
谷歌浏览器:仅对 type=‘text’ 的input有效,即不能自动填充,也不会显示填充提示;而对于密码框 type=‘password’,虽然不会自动填充,但密码框聚焦后会出现填充提示,点击填充提示的账号密码,可以实现自动填充。如图所示:
火狐浏览器:输入框和密码框都不会出现自动填充,但二者聚焦后都会出现填充提示,并都能进行点击后填充。如图所示:
Edge浏览器: autocomplete对该浏览器完全无效。初始化页面即会自动填充账号和密码。
3.二技能:傀儡input,瞒天过海
给text框和password框前后各加一个假的input框,让浏览器的自动填充对假的input框生效,然后用css把假的input框设置为不可见,从而瞒天过海。
<form action="/">
<input id="fakerUserName1" type="text" placeholder="请输入账号" autocomplete="off">
<input id="userName" type="text" placeholder="请输入账号" autocomplete="off">
<input id="fakerUserName2" type="text" placeholder="请输入账号" autocomplete="off">
<input id="fakerUserPwd1" type="password" placeholder="请输入密码" autocomplete="new-password">
<input id="userPwd" type="password" placeholder="请输入密码" autocomplete="new-password">
<input id="fakerUserPwd2" type="password" placeholder="请输入密码" autocomplete="new-password">
<button type="submit">提交</button>
</form>
/* css将假的input设置为不可见 */
input#fakerUserName1,
input#fakerUserName2,
input#fakerUserPwd1,
input#fakerUserPwd2 {
position: fixed;
top: -100%;
left: -100%;
}
谷歌浏览器: 该技能对谷歌的效果与属性autocomplete的效果一样,故与技能一相比无任何变化。即text框既不能填充也无填充提示,password框不能填充但聚焦后有填充提示,并且点击后可自动填充。
火狐浏览器: 该技能对text框有效,既不能自动填充,也不会出现填充提示,对password无效,不能自动填充,但聚焦后有填充提示,点击后可自动填充。如图:
Edge浏览器: 解决了初始化页面即自动填充的问题,对于text框既不能自动填充,也不会出现填充提示,对于password框,不能自动填充,但聚焦后有填充提示,点击后可自动填充。如图:
注意: 添加假的input框时要注意给input的id也要加上,否则可能不起作用,因为不同的浏览器对此有不同的策略,有时,id的字符长短也会产生不同的效果,可自行尝试。
4.三技能:JavaScript出击,直接开大
通过前两个技能,可以发现,这些浏览器的策略是非常激进的,尤其是对于password框。有时无论你添加多少个假的input框,可能对于浏览器而言,它并不在乎,因为只要是 type=‘password’ 的input框,它就会在聚焦后出现填充提示,点击这个填充提示,就又可以实现自动填充。对于某些用户而言,可能由于不小心点击了在浏览器上自动的保存密码,但对于该功能,其账号的安全性便大大降低了,尤其对于某些注重隐私的公司而言,这可能是不可接受的,因为,商战是处处皆有可能的,于是乎,一口大黑锅就甩到了开发人员的身上。
既然如此,开发狗该怎么办呢?
既然技能一和技能二只对 type=‘text’ 的input框有效,那我就不要使用 type=‘password’ 了呗。
嗯!真是大聪明?!
如果这样的话,输入密码的时候不就直接明文输入了吗?
对啊…
滚…
等等,你说什么?
滚…
上一句,输入密码的时候?输入密码的时候??输入密码 的时候 !!!
OK,JavaScript出击!
于是乎,办法出现了,我们可以将 type=‘password’ 改为 type=‘text’ ,然后使用JavaScript监听input事件,实现偷梁换柱,功德圆满!哈哈哈哈哈…
<body>
<form action="/">
<input id="fakerUserName1" type="text" placeholder="请输入账号" autocomplete="off">
<input id="userName" type="text" placeholder="请输入账号" autocomplete="off">
<input id="fakerUserName2" type="text" placeholder="请输入账号" autocomplete="off">
<input id="fakerUserPwd1" type="text" placeholder="请输入密码" autocomplete="new-password">
<input id="userPwd" type="text" placeholder="请输入密码" autocomplete="new-password">
<input id="fakerUserPwd2" type="text" placeholder="请输入密码" autocomplete="new-password">
<button type="submit">提交</button>
</form>
<script>
document.querySelector('#userPwd').addEventListener('input', function () {
this.type = 'password';
})
</script>
</body>
看看效果:
对于浏览器版本的不同可能有些许差异,但问题不大。对于我使用的浏览器的版本,见下图:
SOS: 但与客户的战争还未结束,还是与input有关,也就是输入账号脱敏的问题,也就是实现下图的效果,切莫大意,我刚开始确实低估了它,不过最终也是如愿解决。
欲知后事如何,且听下回分解。
对input输入框脱敏的实现(input输入时可回删、可粘贴)可查看文章:https://blog.csdn.net/qq_51667621/article/details/139988001