一、问题
浏览器自动记住密码是不安全的,因为它记住的都是明文密码。
那么如何不让浏览器记住密码?最简单的做法就是打开浏览器的设置界面,把记住密码功能关掉。然而问题没有这么简单,用户的行为是无法控制的,作为开发者,需要通过编码,来限制用户的行为,避免用户“踩坑”。以下是我们要解决的问题:
- 阻止浏览器自动填充密码
- 解决浏览器兼容问题
- 从源头上防止浏览器记住密码
二、阻止浏览器自动填充密码
一般input标签设置了type="password"
后,记住密码时浏览器会自动填充用户名和密码。网络上有很多做法,但是大多无法解决所有问题。 以下是我尝试过的方法:
解法一: 在input上使用了autocomplete="off"
autocomplete 属性规定输入字段是否应该启用自动完成功能。但是有时候会不起作用,比如在显示页面的时候可能会启用自动完成功能,导致页面显示出现问题。查阅资料后把属性值改为:new-password,即autocomplete="new-password"
,部分浏览器生效了,但是某些浏览器仍然可以写入密码。
解法二: 在用户名的最前面放一个隐藏的输入框和一个隐藏是密码框此方法对IE有效
解法三: 设置type="text" onfocus="this.type='password'"。这个方法基本阻止了首次进入页面时浏览器填充密码,但是换火狐浏览器试了一下,在输入数据后再删空数据又会出现密码填充的下拉提示。
解法四: 放两个输入框属性全部一致,一个type=’text’另一个type=’passward’,绑定同一个变量,这个变量为空时显示type=’text’的输入框,并触发focus事件,把光标聚焦到显示的输入框中,另一个隐藏;不为空时则相反。经过测试,ie浏览器有一个问题,变量从空变成有值时,触发focus后,光标是在输入框的最前面,而不是最后面。
<el-input
v-show="type==='text'"
key="password1"
ref="password1"
v-model.trim="loginForm.password"
type="text"
tabindex="2"
autocomplete="new-password"
@blur="handleBlur"
@keyup.native="checkCapslock"
@paste.native.capture.prevent="()=>{}"
@keyup.enter.native="handleEnter"
/>
<el-input
v-show="type==='password'"
key="password2"
ref="password2"
v-model.trim="loginForm.password"
type="password"
tabindex="2"
autocomplete="new-password"
@blur="handleBlur"
@keyup.native="checkCapslock"
@paste.native.capture.prevent="()=>{}"
@keyup.enter.native="handleEnter"
/>
computed: {
type() {
if (this.loginForm.password) {
return 'password'
} else {
return 'text'
}
}
},
watch: {
type(val, old) {
if (val === 'password') {
this.$nextTick(() => {
this.$refs.password2.focus()
})
} else {
this.$nextTick(() => {
this.$refs.password1.focus()
})
}
}
},
三、解决浏览器兼容问题
经过尝试发现没有一种方法能够适配所有浏览器,因此把以上解法一、解法二、解法四都加上,再对出现问题的部分浏览器做特殊定制处理。以下方法可识别是什么浏览器
// 获取浏览器
export function getExplorer() {
var explorer = window.navigator.userAgent
var compare = function(s) {
return (explorer.indexOf(s) >= 0)
}
var ie11 = (function() {
return ('ActiveXObject' in window)
})()
if (compare('MSIE') || ie11) {
return 'ie'
} else if (compare('Firefox') && !ie11) {
return 'Firefox'
} else if (compare('Chrome') && !ie11) {
if (explorer.indexOf('Edge') > -1) {
return 'Edge'
} else {
return 'Chrome'
}
} else if (compare('Opera') && !ie11) {
return 'Opera'
} else if (compare('Safari') && !ie11) {
return 'Safari'
}
return ''
}
if (getExplorer == 'ie') {
alert('当前浏览器内核为IE内核,请使用非IE内核浏览器!')
}
if (getExplorer == 'Edge') {
alert('当前浏览器为Edge,请使用非IE内核浏览器!')
}
例如:让解法四的代码在浏览器为ie和Edge时不执行,则不会出现输入框的异常问题。解法二则对这两个浏览器能够生效。
computed: {
type() {
if (this.explorer === 'ie' || this.explorer === 'Edge') {
return 'password'
}
if (this.loginForm.password) {
return 'password'
} else {
return 'text'
}
}
},
四、防止浏览器记住密码
解决了密码自动填充的问题,但是,浏览器仍然能将输入的密码记住到浏览器,仍然是不安全的,因此,需要防止密码被浏览器记录,从源头上切断风险。
经过查询,以及参考友商做法。由于大多数浏览器记录账号密码发生在跳转页面时,读取表单内的信息。所以最终方案:登陆成功跳转前,清空表单账号密码。
//登录成功时
this.loginForm.username = ''
this.loginForm.password = ''
this.$router.push({ path: '/' })
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。