Node.js登录接口实现密码错误次数限制与账户锁定

作者:后端茶话

时间:2026-10-23

浏览:70

本文详解在Node.js登录接口中实现密码错误尝试次数限制的方法。通过数据库记录失败日期与次数,结合Crypto模块进行MD5双重加密,当错误次数超过阈值时锁定账户并返回提示,有效防止暴力破解,保障用户账户安全。

文章目录

Node.js登录接口实现密码错误次数限制与账户锁定

限制密码尝试次数能够有效保护用户账户安全。即使面对量子计算机等强大算力,这种限制机制也能使其难以突破。

这一机制类似于银行卡账户,当尝试次数过多时,系统会自动锁定账户,甚至可能触发自动报警功能。

具体效果如下图所示。

Node.js登录接口实现密码错误次数限制与账户锁定 

实现思路与数据库设计

实现思路如下。

首先需要设计数据库表结构。

在数据库表中添加一个字符串类型的字段,用于存储两个关键数据:密码失败尝试日期和尝试次数,格式参考 2019a10a23|10。此处使用竖线“|”作为数据段的分割符,字母“a”作为日期各部分的分割符。

代码逻辑与封装

接下来梳理代码逻辑。

如果记录的日期与当天相同,则在密码输入错误时,执行 次数+1 操作。

如果记录的日期不是当天,则重置相关计数。

将上述逻辑封装为独立模块。

以下是实现该功能的简化代码封装。

该示例仅实现了一天内的简单次数校验,更高级的规则需要根据实际需求自行修改。


/**
 * 尝试登录次数限制
 * 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算法进行双重加密,目的是即使内部员工获取了数据库中的密码哈希值,也难以直接登录。该功能依赖Node.js内置的 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: '服务器错误'
    })
  })
})

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

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章