提交 e513946d 编写于 作者: 雪洛's avatar 雪洛

feat: passwordErrorLimit

上级 69d0074a
......@@ -8,6 +8,7 @@ const ERROR = {
ACCOUNT_CLOSED: 'uni-id-account-closed',
CAPTCHA_REQUIRED: 'uni-id-captcha-required',
PASSWORD_ERROR: 'uni-id-password-error',
PASSWORD_ERROR_EXCEED_LIMIT: 'uni-id-password-error-exceed-limit',
INVALID_USERNAME: 'uni-id-invalid-username',
INVALID_PASSWORD: 'uni-id-invalid-password',
INVALID_MOBILE: 'uni-id-invalid-mobile',
......
......@@ -13,6 +13,7 @@ const sentence = {
'uni-id-account-closed': 'Account has been closed',
'uni-id-captcha-required': 'Captcha required',
'uni-id-password-error': 'Username or password error',
'uni-id-password-error-exceed-limit': 'The number of password errors is excessive',
'uni-id-invalid-username': 'Invalid username',
'uni-id-invalid-password': 'invalid password',
'uni-id-invalid-mobile': 'Invalid mobile phone number',
......
......@@ -13,6 +13,7 @@ const sentence = {
'uni-id-account-closed': '此账号已注销',
'uni-id-captcha-required': '请输入图形验证码',
'uni-id-password-error': '用户名或密码错误',
'uni-id-password-error-exceed-limit': '密码错误次数过多,请稍后再试',
'uni-id-invalid-username': '用户名不合法',
'uni-id-invalid-password': '密码不合法',
'uni-id-invalid-mobile': '手机号码不合法',
......
......@@ -57,9 +57,27 @@ async function preLoginWithPassword (params = {}) {
} = params
try {
const userRecord = await realPreLogin.call(this, params)
const {
passwordErrorLimit,
passwordErrorRetryTime
} = this.config
const {
clientIP
} = this.getClientInfo()
// 根据ip地址,密码错误次数过多,锁定登录
let loginIPLimit = userRecord.login_ip_limit || []
// 清理无用记录
loginIPLimit = loginIPLimit.filter(item => item.last_error_time > Date.now() - passwordErrorRetryTime * 1000)
let currentIPLimit = loginIPLimit.find(item => item.ip === clientIP)
if (currentIPLimit && currentIPLimit.error_times >= passwordErrorLimit) {
throw {
errCode: ERROR.PASSWORD_ERROR_EXCEED_LIMIT
}
}
const passwordUtils = new PasswordUtils({
passwordSecret: this.config.passwordSecret
})
const {
success: checkPasswordSuccess,
refreshPasswordInfo
......@@ -69,6 +87,21 @@ async function preLoginWithPassword (params = {}) {
passwordSecretVersion: userRecord.password_secret_version
})
if (!checkPasswordSuccess) {
// 更新用户ip对应的密码错误记录
if (!currentIPLimit) {
currentIPLimit = {
ip: clientIP,
error_times: 1,
last_error_time: Date.now()
}
loginIPLimit.push(currentIPLimit)
} else {
currentIPLimit.error_times++
currentIPLimit.last_error_time = Date.now()
}
await userCollection.doc(userRecord._id).update({
login_ip_limit: loginIPLimit
})
throw {
errCode: ERROR.PASSWORD_ERROR
}
......@@ -78,6 +111,12 @@ async function preLoginWithPassword (params = {}) {
extraData.password = refreshPasswordInfo.passwordHash
extraData.password_secret_version = refreshPasswordInfo.version
}
const currentIPLimitIndex = loginIPLimit.indexOf(currentIPLimit)
if (currentIPLimitIndex > -1) {
loginIPLimit.splice(currentIPLimitIndex, 1)
}
extraData.login_ip_limit = loginIPLimit
return {
user: userRecord,
extraData
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册