之前我们为web2py框架改造增加了本地验证码功能,另一个提升信息安全的常用手段是用户密码管理策略:
在密码强度方面,web2py自带的强密码策略可以通过IS_STRONG自由
设定,可设定长度,组合等等,功能已经很丰富(详见官方手册说明),这块到不用我们动手修改。
另外一个常用的密码管理策略是,用户必须第1次登录和定期强制修改密码,今天我们动手改造这块,本次改造需要改gluon下的tools.py源码,同时为auth_user表扩充一个字段:
一、auth_user表扩充一个字段:
新字段用于记录最近一次更新密码日期,在db.py文件中添加一行:
auth.settings.extra_fields['auth_user'] = [Field('PWmod','date',writable=False,label='密码修改日期')]
二、Auth类下的login方法修改
1、login方法修改
在login方法中,在 if session.auth_two_factor_user is None:这整个一段分支后紧接着添加以下代码。
# todo:判断是否密码过期或第一次登录
if user:
if not user.PWmod or (datetime.date.today() - user.PWmod).days > 90:
session.auth_need_mod_PW = True
if session.auth_need_mod_PW :
# store the validated user and associate with this session
if session.auth_need_mod_PW_user is None and user is not None:
session.auth_need_mod_PW_user = user
table_user = self.table_user()
form = SQLFORM.factory(Field('old_password','password',label='请输入旧密码',requires=table_user['password'].requires,),
Field('new_password','password',label='请输入新密码',requires=table_user['password'].requires,),
Field('new_password2','password',label='再次输入新密码',comment='第一次登录或密码每90天需要修改',
requires=[IS_EXPR('value==%s' % repr(request.vars.new_password),
'两次输入的新密码不一致')]))
if form.accepts(request, session, onvalidation=onvalidation):
if not form.vars['old_password'] == session.auth_need_mod_PW_user['password']:
form.errors['old_password'] = '旧密码不对呢'
return form
elif form.vars['old_password'] == form.vars['new_password']:
form.errors['new_password'] = '新密码不能跟旧密码一样啊'
return form
else:
session.auth_need_mod_PW = False
current.db(table_user.id == session.auth_need_mod_PW_user.id).update(password=str(form.vars.new_password),
PWmod=datetime.date.today())
session.flash = '密码已修改,请用新密码重新登录'
redirect(URL('default','user',args='login'))
else:
return form
2、change_password方法修改
这个是框架自带的用户在前台修改自己密码的方法,这里也需要改以下,用户改了密码要也同步更新下用户的最近一次密码修改日期,这里加1行就行,就在源代码更新密码这行:
s.update(**d)
的下面再加一行,PWmod字段是我们自己拓展的字段名称:
s.update(PWmod=datetime.date.today())
三、其他补充
如果你在应用中还开放了系统自带的变更密码的方法,例如:重置reset_password、邮件重置email_reset_password等,这些方法中也应该同步更新PWmod字段日期。