如何在前端实现用户不能重复使用最近3次密码的验证?
在做用户密码修改功能时,需要限制用户不能重复使用最近3次的密码。我用Vue写了表单验证,但不知道该怎么存储和比对历史密码:
<template>
<form @submit.prevent="updatePassword">
<input type="password" v-model="newPassword" required>
<button>提交</button>
</form>
</template>
<script>
export default {
data() {
return {
newPassword: '',
// 这里该怎样保存历史密码?
passwordHistory: []
}
},
methods: {
updatePassword() {
// 如何检查新密码是否在历史记录里?
if (this.passwordHistory.includes(this.newPassword)) {
alert('不能重复使用最近3次的密码')
}
}
}
}
</script>
我尝试用数组存最近三次密码,但页面刷新后数据就丢失了。如果用localStorage存储明文密码好像很不安全,但直接让后端返回加密后的历史记录又怕被前端解析。现在卡在这一步,该用什么方式实现既安全又符合要求的验证呢?
前端肯定不能存明文历史密码,用localStorage也不行。正确的做法是让用户提交新密码时,后端先验证这个密码是否和数据库里最近三次加密后的记录重复了。前端只做表单验证,真正的密码比对必须交给后端。
你现在的思路没错,但要改。你不需要在前端保存明文历史密码,只需要在提交时把用户输入的新密码发给后端。后端拿到密码后,先用同样的加密算法处理,再和用户最近三次加密后的密码对比。如果匹配上了,再返回错误信息。
前端这边可以加一个提示:"新密码不能与最近三次密码重复",但不要做实际验证。因为加密逻辑在后端,前端验证只是辅助,不是必须的。
所以你的代码里不用存passwordHistory,直接删掉。提交时让后端去判断就行。
如果产品硬要前端实时提示,那也得后端配合。比如在登录时返回用户最近三次密码的哈希值,但这些哈希值是加密过的,前端无法反推原始密码。然后前端用crypto库把用户输入的密码加密后,去比对这三个哈希值。但这会增加复杂度,一般还是让后端处理比较稳妥。
总之,密码这种敏感数据,验证逻辑一定要以后端为准。前端最多做提示,不能做决策。