前面文章我们改造增加了 “web2py增加第一次登录和定期强制修改密码功能”和“web2py增加登录图片验证码改造”功能,另外一个信息安全管理常用的功能点是:如果用户连续N次登录密码错误自动锁定用户,N根据自己需求设定。本次改造需要改gluon下的tools.py源码,同时为auth_user表扩充一个字段:
一、auth_user表扩充一个字段:
新字段用于记录连续错误次数,在db.py文件中添加:
auth.settings.extra_fields['auth_user'] = [Field('pwWrong','integer',label='密码错误次数')]
二、Auth类下的login方法修改
搜索"if settings.login_form == self:"段落
原来长这样:
if settings.login_form == self:
form = SQLFORM(table_user,
fields=[username, passfield],
hidden=dict(_next=next),
showid=settings.showid,
submit_button=self.messages.login_button,
delete_label=self.messages.delete_label,
formstyle=settings.formstyle,
separator=settings.label_separator,
extra_fields=extra_fields,
)
....
....
....
....
if form.accepts(request, session if self.csrf_prevention else None,
formname='login', dbio=False,
onvalidation=onvalidation,
hideerror=settings.hideerror):
....
....
....
....
if user:
.....
.....
.....
if not user:
# alternates have failed, maybe because service inaccessible
if settings.login_methods[0] == self:
# try logging in locally using cached credentials
if form.vars.get(passfield, '') == temp_user[passfield]:
# success
user = temp_user
改成这样:
if settings.login_form == self:
form = SQLFORM(table_user,
fields=[username, passfield],
hidden=dict(_next=next),
showid=settings.showid,
submit_button=self.messages.login_button,
delete_label=self.messages.delete_label,
formstyle=settings.formstyle,
separator=settings.label_separator,
extra_fields=extra_fields,
)
....
....
....
....
if form.accepts(request, session if self.csrf_prevention else None,
formname='login', dbio=False,
onvalidation=onvalidation,
hideerror=settings.hideerror):
....
....
....
....
if user:
# todo 锁定账号不再后续验证
if user.pwWrong == 0:
session.flash = '账号密码已连续输错5次,账号已锁定'
redirect(self.url(args=request.args, vars=request.get_vars),client_side=settings.client_side)
.....
.....
.....
if not user:
# alternates have failed, maybe because service inaccessible
if settings.login_methods[0] == self:
# try logging in locally using cached credentials
if form.vars.get(passfield, '') == temp_user[passfield]:
# success
user = temp_user
# todo 输对了就重置次数
if user.pwWrong != 5:
current.db(table_user.id == user.id).update(pwWrong=5)
current.db.commit()
# todo 用户名对,密码不对,则5次密码错误后,锁定用户
else:
if temp_user.pwWrong != None:
current.db(table_user.id == temp_user.id).update(pwWrong=temp_user.pwWrong-1)
current.db.commit()
else:
current.db(table_user.id == temp_user.id).update(pwWrong=4)
current.db.commit()
session.flash = '密码错误,连续输错5次账号将锁定,还剩'+str(table_user[temp_user.id].pwWrong)+'次机会'
redirect(self.url(args=request.args, vars=request.get_vars),client_side=settings.client_side)