JavaScript

超轻量级php框架startmvc

详解node登录接口之密码错误限制次数(含代码)

更新时间:2020-09-18 16:48 作者:startmvc
密码次数尝试,可以有效的保护用户账户安全,有了限制之后,就算用量子计算机都束手无

密码次数尝试,可以有效的保护用户账户安全,有了限制之后,就算用量子计算机都束手无策。

银行卡也是这种,尝试次数过多,就锁定,说不定还会自动报警。

效果图

 

实现思路

 数据库表设计

在表里面添加一个字段,string类型。里面包含两个数据,密码失败尝试日期 和 次数 如 2019a10a23|10 这里我使用|做数据段分割,a字母做日期分割

代码逻辑

当记录的日期是当天,那么密码错误的时候, 次数+1

当记录的日期不是当天,那么重置

代码封装

这是我实现的简单代码封装

(这里只实现了一天内x次的简单校验,高级规则需要自己改)


/**
 * 尝试登录次数限制
 * login_number [日期, 次数].join('|')
 * 更新到数据库 (更新数据) => {}
 * return {
 * run bool true: 超过 false: 正常
 * start 登录失败后修改状态
 * }
 */
exports.Login_n = (login_number, 更新到数据库) => {
 let run = true
 let 当日登录次数 = 0
 let 当日最多尝试次数 = 10
 var getD = () => {
 var date = new Date()
 var d = [date.getUTCFullYear(), date.getMonth() + 1, date.getDate()].join('a')
 return d
 }
 if(login_number){
 let date = login_number.split('|')[0]
 let n = login_number.split('|')[1]
 if(date == getD()){
 当日登录次数 = (+n)
 }
 }
 if(当日登录次数 >= 当日最多尝试次数){
 run = false
 }
 let 登录失败后修改状态函数 = () => {
 let add_login_number
 let 非当日 = () => {
 更新到数据库([getD(), 0].join('|'))
 }
 let 今天 = (n) => {
 更新到数据库([getD(), n].join('|'))
 }
 if(!login_number){
 非当日()
 }else{
 let date = login_number.split('|')[0]
 let n = login_number.split('|')[1]
 if(date == getD()){
 今天((+n) + 1)
 }
 }
 }
 return {
 run,
 start: 登录失败后修改状态函数
 }
}

使用

引入 & 设置状态


var { Login_n } = require('./login_n')
var login_n = Login_n(login_number, (v) => {
 db('all', 'update t_user set login_number=? where id=?', [v, id]).then(results => {
 console.log('修改登录失败次数记录成功')
 })
})

拦截


if(!login_n.run){
 resolve({
 code: 1,
 msg: '账户异常锁定, 请明天再试'
 })
 return
}

密码错误开始记录


if(results[0].pw !== pw){
 // 登录失败,更新登录次数
 login_n.start()
	resolve({
 code: 1,
 msg: '密码错误'
 })
	return
} 

登录完整代码

需要引入上面的(错误限制次数代码)

这里的md5,是为了双重加密,当内部员工拿到数据库密码后也不容易登录, 依赖nodejs内置包 crypto


var crypto = require('crypto')
exports.phone_pw_login = (params, req) => new Promise((resolve, reject) => {
 var { Login_n } = require('./login_n')
 let {pass, phone} = params
 var md5 = crypto.createHash("md5");
 let pw = md5.update(pass).digest('hex').toUpperCase()
 db('all', 'SELECT phone, pw, id, name, login_number from t_user WHERE phone=?', [phone]).then(results => {
 let { login_number, id } = results[0]
 // 账号不存在
 if(results.length == 0){
 resolve({
 code: 1,
 msg: '密码错误', // 避免得知是否注册账号
 })
 return
 }

 // 次数校验
 var login_n = Login_n(login_number, (v) => {
 db('all', 'update t_user set login_number=? where id=?', [v, id]).then(results => {
 console.log('修改登录失败次数记录成功')
 })
 })
 if(!login_n.run){
 resolve({
 code: 1,
 msg: '账户异常锁定, 请明天再试'
 })
 return
 }

 if(results[0].pw !== pw){
 // 登录失败,更新登录次数
 login_n.start()
 resolve({
 code: 1,
 msg: '密码错误'
 })
 return
 } 
 let token = Jwt.Create({phone: results[0].phone, id: id, pw})
 
 resolve({
 code: 200,
 msg: {
 name: results[0].name,
 phone: results[0].phone,
 token,
 }
 })
 })
 .catch(error => {
 console.log(error)
 resolve({
 code: 1,
 msg: '服务器错误'
 })
 })
})

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。