From d6af402dfc6075cf438fe102eccac16b73c115dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E9=9D=96=E6=80=A1?= <3060819641@qq.com> Date: Fri, 30 May 2025 10:46:21 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BD=BF=E7=94=A8=E5=9B=BA=E5=AE=9A=E7=9B=90?= =?UTF-8?q?=E5=80=BC=E5=A2=9E=E5=BC=BA=E5=AF=86=E7=A0=81=E5=AE=89=E5=85=A8?= =?UTF-8?q?=E6=80=A7=EF=BC=8C=E6=8F=90=E9=AB=98=E5=AF=86=E7=A0=81=E6=9C=80?= =?UTF-8?q?=E5=B0=8F=E9=95=BF=E5=BA=A6=E8=A6=81=E6=B1=82=E5=B9=B6=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E9=A2=9D=E5=A4=96=E7=9A=84=E5=AE=89=E5=85=A8=E6=A3=80?= =?UTF-8?q?=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Login.py | 95 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 56 insertions(+), 39 deletions(-) diff --git a/app/Login.py b/app/Login.py index d82a6d1..384d6e5 100644 --- a/app/Login.py +++ b/app/Login.py @@ -3,6 +3,8 @@ import string from datetime import datetime, timedelta import unicodedata +# 使用固定盐值增强密码安全性 +PASSWORD_SALT = "wordfreq_salt_2023" def md5(s): ''' @@ -13,32 +15,40 @@ def md5(s): h = hashlib.md5(s.encode(encoding='utf-8')) return h.hexdigest() - -# import model.user after the defination of md5(s) to avoid circular import -from model.user import get_user_by_username, insert_user, update_password_by_username - +# 延迟导入 model.user,避免循环导入 path_prefix = '/var/www/wordfreq/wordfreq/' path_prefix = './' # comment this line in deployment - def verify_user(username, password): + '''验证用户凭据''' + from model.user import get_user_by_username # 延迟导入 user = get_user_by_username(username) - encoded_password = md5(username + password) - return user is not None and user.password == encoded_password - + if user is None: + return False + + # 使用带盐值的加密 + encrypted_password = md5(PASSWORD_SALT + username + password) + return user.password == encrypted_password def add_user(username, password): start_date = datetime.now().strftime('%Y%m%d') expiry_date = (datetime.now() + timedelta(days=30)).strftime('%Y%m%d') # will expire after 30 days - # 将用户名和密码一起加密,以免暴露不同用户的相同密码 - password = md5(username + password) - insert_user(username=username, password=password, start_date=start_date, expiry_date=expiry_date) - + + # 使用带盐值的加密 + encrypted_password = md5(PASSWORD_SALT + username + password) + + from model.user import insert_user # 延迟导入 + insert_user( + username=username, + password=encrypted_password, + start_date=start_date, + expiry_date=expiry_date + ) def check_username_availability(username): - existed_user = get_user_by_username(username) - return existed_user is None - + # 延迟导入,避免循环导入 + from model.user import get_user_by_username + return get_user_by_username(username) is None def change_password(username, old_password, new_password): ''' @@ -53,17 +63,19 @@ def change_password(username, old_password, new_password): # 将用户名和密码一起加密,以免暴露不同用户的相同密码 if new_password == old_password: #新旧密码一致 return {'error':'New password cannot be the same as the old password.', 'username':username} - update_password_by_username(username, new_password) - return {'success':'Password changed', 'username':username} - + + # 加密新密码(修复了原代码未加密的安全漏洞) + encrypted_new_password = md5(PASSWORD_SALT + username + new_password) + # 延迟导入,避免循环导入 + from model.user import update_password_by_username + update_password_by_username(username, encrypted_new_password) + return {'success': 'Password changed', 'username':username} def get_expiry_date(username): + # 延迟导入,避免循环导入 + from model.user import get_user_by_username user = get_user_by_username(username) - if user is None: - return '20191024' - else: - return user.expiry_date - + return user.expiry_date if user else '20191024' # 默认过期日期 class UserName: def __init__(self, username): @@ -75,7 +87,7 @@ class UserName: if unicodedata.name(char).startswith('CJK UNIFIED IDEOGRAPH'): return True return False - + def validate(self): if len(self.username) > 20: return f'{self.username} is too long. The user name cannot exceed 20 characters.' @@ -93,35 +105,40 @@ class UserName: return 'Chinese characters are not allowed in the user name.' return 'OK' - class Password: + '''密码验证类''' def __init__(self, password): self.password = password - - def contains_chinese(self): + + def contains_cjk(self): for char in self.password: # Check if the character is in the CJK (Chinese, Japanese, Korean) Unicode block if unicodedata.name(char).startswith('CJK UNIFIED IDEOGRAPH'): return True return False - + def validate(self): - if len(self.password) < 4: + '''验证密码有效性''' + if len(self.password) < 6: # 提高最小长度要求 return 'Password must be at least 4 characters long.' if ' ' in self.password: return 'Password cannot contain spaces.' - if self.contains_chinese(): + if self.contains_cjk(): return 'Chinese characters are not allowed in the password.' + # 添加额外的安全检查 + if not any(char.isdigit() for char in self.password): + return '密码应包含至少一个数字' return 'OK' - class WarningMessage: - def __init__(self, s, type='username'): - self.s = s - self.type = type - + '''验证消息生成类''' + def __init__(self, input_str, input_type='username'): + self.input_str = input_str + self.input_type = input_type + def __str__(self): - if self.type == 'username': - return UserName(self.s).validate() - if self.type == 'password': - return Password(self.s).validate() + if self.input_type == 'username': + return UserName(self.input_str).validate() + if self.input_type == 'password': + return Password(self.input_str).validate() + return '未知验证类型' \ No newline at end of file