Python模拟用户验证的程序
写在前面的
每一个系统,第一步操作基本都是先用户登录。登录后,在用户使用相应功能时,都需要先验证用户权限,再显示相应权限范围内的信息。这样才能保证用户不会越权使用系统。
用户登录验证的方式很多,但想起来简单,做起来也不难,但做好似乎又不是那么容易。
这里就以一个简单的代码结构模拟用户登录及用户验证的结构。
1.需求描述
- 用户可能通过用户名密码进行系统登录
- 当用户名不存在时提示 “用户不存在”
- 用户未登录时:
- 当用户密码不匹配时提示 “用户名密码不正确”
- 当用户密码为空是提示 “用户密码不能为空”
- 当用户名密码匹配时提示 “用户登录成功”
- 查询用户信息,用户只能查询自己的信息
- 登录系统用户与查询用户的用户名不相同时,提示 “您无权查询此用户信息”
- 登录系统用户与查询用户的用户名不相同时, 显示用户信息
2.设计描述
2.1 用户信息
使用一个字典模拟数据库存放的用户信息,用户信息包含:
字段名 | 格式 | 说明 |
---|---|---|
用户名 | 字符串 | |
密码 | 加密后的字符串 | Md5加密 |
是否已登录 | bool | 0-未登录 1-已登录 |
登录时间 | datetime |
使用文件来存放用户数据字典:
初始化用户,使用一个函数将创建4个用户账号,并将账号存放在字典中返回。
创建一个用户类处理文件读写,用户创建,数据初始化操作
class User:
# staticmethod:user_list = dict()
user_list = {}
user_file = r".\user1.bin"
def __init__(self):
self.user_list = self.InitUserInfo()
# 写数据到用户数据文件
def OutToFile(self, oUsers=None):
if oUsers == None:
oUsers = self.InitUserInfo()
with open(self.user_file, 'wb') as f:
f.write(json.dumps(oUsers).encode("utf-8"))
f.flush()
f.close()
# 从数据文件读数据
def ReadFromFile(self):
with open(self.user_file, 'rb') as f:
data = f.read()
f.close()
return json.loads(data)
# 创建用户
def BuildUser(self, *args):
'''
args[0]: UserName
args[1]: Password
'''
oUserInfo = {
'UserName': args[0],
'PassWord': hashlib.md5(args[1].encode('utf-8')).hexdigest(),
'IsLogin': 0,
'LastTime': datetime.today().strftime("%Y-%m-%d %H:%I:%S")
}
return oUserInfo
# 初始化用户数据
def InitUserInfo(self):
user_dict = dict()
user_dict["A01"] =self.BuildUser("U01","123")
user_dict["A02"] =self.BuildUser("U02","123")
user_dict["A03"] =self.BuildUser("U03","123")
user_dict["A04"] =self.BuildUser("U04","123")
return user_dict
2.2 验证用户
创建两个闭包函数
一个用来在验证用户信息时,通过装饰器模式来验证用户状态。函数将需要最多两个参数,第一个参数为用户名,第二个参数为密码。如果仅验证用户状态,则只需要传入第一个用户名即可。
一个用来实现用户登出操作,通过装饰器模式来更新用户状态为登出。
- 这里通过使用一个列表参数 *args 来实现不定数量参数。
- 通过hashlib库的md5来加密码密码
- 在只有验证通过时才会执行装饰器对应的函数
# 验证用户状态
# 01 - 用户不存在
# 02 - 用户密码不能为空
# 03 - 用户名密码不正确!
# 00 - 用户登录成功
def ValidUser(func):
def UserStatus(*args):
user_name = pass_word = None
if len(args) >= 1:
user_name = args[0]
if len(args) >= 2:
pass_word = hashlib.md5(args[1].encode('utf-8')).hexdigest()
# oUser = User()
# staticmethod:user_list = oUser.InitUserInfo()# .user_list.get(user_name)
oUser = User()
user_list = oUser.ReadFromFile()
u = user_list.get(user_name)
if u == None:
return '01','用户不存在'
elif u["IsLogin"] == 1:
func(*args)
return '04', '用户验证未通过'
elif (pass_word == None):
return '02','用户密码不能为空!'
elif (pass_word != u["PassWord"]):
return '03', '用户名密码不正确!'
else:
u["IsLogin"] = 1
u["LastTime"] = datetime.now().strftime("%Y-%m-%d %H:%I:%S")
oUser.OutToFile(user_list)
func(*args)
return '00', '用户登录成功'
return UserStatus
# 用户登出
# 01 - 用户不存在
# 00 - 用户登出成功
def UserLogout(func):
def UserStatus(*args):
user_name = None
if len(args) >= 1:
user_name = args[0]
oUser = User()
user_list = oUser.ReadFromFile()
u = user_list.get(user_name)
if u == None:
return '01','用户不存在'
else:
u["IsLogin"] = 0
oUser.OutToFile(user_list)
func(user_name)
return '00', '用户登出成功'
return UserStatus
2.3 用户操作函数
2.3.1 用户登录
函数名:login
- 应用装饰器:ValidUser
- 参数
- 用户名:user_name
- 密码:user_pass
@ValidUser
def Login(user_name,user_pass):
print("用户%s登录成功" % (user_name,))
2.3.2 用户登出
函数名:logout
- 应用装饰器:UserLogout
- 参数
- 用户名:user_name
@ValidUser
def Logout(user_name):
print("用户%s已登出" % (user_name,))
2.3.2 查询用户信息
函数名:ViewUserInfo
- 应用装饰器:ValidUser
- 参数
- 用户名:user_name
@UserLogout
def ViewUserInfo(user_name):
u = staticmethod.user_list.get(user_name)
print(u)
3 完整代码
4. 验证结果
4.1 验证步骤
4.1.1 数据初始化
- 引入代码文件:
import user_login as user
- 初始化用户信息
此函数会创建一个文件到程序执行目录下,并且将程序里预设的用户信息写入新创建的文件中。
oUser = user.User()
oUser.OutToFile()
- 查看用户信息
此函数从前面已创建的用户文件中读取数据,并打印的运行窗口。
oUser.ReadFromFile()
4.1.2 用户操作
- 用户登入
此函数为演示实际用户登录操作,只需要输入参数 user_name ,user_pass,即可完成账号验证操作,并返回登录是否成功提示信息。
@ValidUser
def Login(user_name, user_pass):
print("用户%s登录成功" % (user_name,))
- 用户查看信息
此函数演示验证用户权限范围,并且不能查看其它账号信息。如果验证是登录用户,则返回用户信息,反之则返回相应提示信息。
@ValidUser
def ViewUserInfo(user_name):
u = staticmethod.user_list.get(user_name)
print(u)
- 用户登出
此函数为演示实际用户登出操作,只需要输入参数 user_name, 即可完成账号登录状态变更操作。
@UserLogout
def Logout(user_name):
print("用户%s已登出" % (user_name,))
4.2 查看初始化数据
4.1.1 初始化数据过程
如下命令执行过程,通过ReadFromFile可以看到输出了所有用户信息。
>>> import user_login as user
>>> oUser = user.User()
>>> oUser.OutToFile()
>>> oUser.ReadFromFile()
{'A01': {'UserName': 'U01', 'PassWord': '202cb962ac59075b964b07152d234b70', 'IsLogin': 0, 'LastTime': '2022-07-31 18:06:17'}, 'A02': {'UserName': 'U02', 'PassWord': '202cb962ac59075b964b07152d234b70', 'IsLogin': 0, 'LastTime': '2022-07-31 18:06:17'}, 'A03': {'UserName': 'U03', 'PassWord': '202cb962ac59075b964b07152d234b70', 'IsLogin': 0, 'LastTime': '2022-07-31 18:06:17'}, 'A04': {'UserName': 'U04', 'PassWord': '202cb962ac59075b964b07152d234b70', 'IsLogin': 0, 'LastTime': '2022-07-31 18:06:17'}}
>>>
4.3 用户操作结果
4.3.1 用户登录
4.3.1.1 用户登录过程测试
>>> import user_login as user
>>> user.Login("ABC")
('01', '用户不存在')
>>> user.Login("A01")
('02', '用户密码不能为空!')
>>> user.Login("A01","12344")
('03', '用户名密码不正确!')
>>> user.Login("A01","123")
用户A01登录成功
('00', '用户登录成功')
4.3.1.2 用户登录后查看数据
可以看到A01的用户的登录状态字段IsLogin已经被置为1
>>> import user_login as user
>>> oUser = user.User()
>>> oUser.ReadFromFile()
{'A01': {'UserName': 'U01', 'PassWord': '202cb962ac59075b964b07152d234b70', 'IsLogin': 1, 'LastTime': '2022-07-31 18:06:39'}, 'A02': {'UserName': 'U02', 'PassWord': '202cb962ac59075b964b07152d234b70', 'IsLogin': 0, 'LastTime': '2022-07-31 18:06:17'}, 'A03': {'UserName': 'U03', 'PassWord': '202cb962ac59075b964b07152d234b70', 'IsLogin': 0, 'LastTime': '2022-07-31 18:06:17'}, 'A04': {'UserName': 'U04', 'PassWord': '202cb962ac59075b964b07152d234b70', 'IsLogin': 0, 'LastTime': '2022-07-31 18:06:17'}}
>>>
4.3.2 用户查看信息
可以看到,当输入参数不是已经登录用户,则返回相应验证结果。当输入的参数是已经登录用户时,输入了相对应的用户信息。
>>> import user_login as user
>>> user.ViewUserInfo("U01")
('01', '用户不存在')
>>> user.ViewUserInfo("A02")
('02', '用户密码不能为空!')
>>> user.ViewUserInfo("A01")
{'UserName': 'U01', 'PassWord': '202cb962ac59075b964b07152d234b70', 'IsLogin': 1, 'LastTime': '2022-07-31 18:06:39'}
('04', '用户验证未通过')
>>>
4.3.3 用户登出
4.3.3.1 用户登出操作
可以看到,当输入的参数是已经登录用户已经登录用户时,执行返回输出结果为用户A01已登出,表示用户已经成功登出。
import user_login as user
>>> user.Logout("A01")
用户A01已登出
('00', '用户登出成功')
>>>
4.3.3.2 用户登出后查看数据
此时查看数据,可以看到用户A01的登录状态IsLogin已经变更为登出状态。
import user_login as user
>>> oUser = user.User ()
>>> oUser.ReadFromFile()
{'A01': {'UserName': 'U01', 'PassWord': '202cb962ac59075b964b07152d234b70', 'IsLogin': 0, 'LastTime': '2022-07-31 18:06:39'}, 'A02': {'UserName': 'U02', 'PassWord': '202cb962ac59075b964b07152d234b70', 'IsLogin': 0, 'LastTime': '2022-07-31 18:06:17'}, 'A03': {'UserName': 'U03', 'PassWord': '202cb962ac59075b964b07152d234b70', 'IsLogin': 0, 'LastTime': '2022-07-31 18:06:17'}, 'A04': {'UserName': 'U04', 'PassWord': '202cb962ac59075b964b07152d234b70', 'IsLogin': 0, 'LastTime': '2022-07-31 18:06:17'}}
>>>
5 总结
用户登录是一个很重要的部分,在实际工作中,其实预见的并不多,因为在工人中,多数情况是负责项目中的一个模块,很少预到登录模块。如果二次开发,或公司系统维护就可能性更小,因为这部分需要修改的机率很低。但是还是需要了解其工作方式。本文是以装饰器的方式。当然还有很多实现方式,要在实际项目中发现。