Python模拟用户验证的程序

发布于:2023-02-05 ⋅ 阅读:(2510) ⋅ 点赞:(2)

写在前面的

每一个系统,第一步操作基本都是先用户登录。登录后,在用户使用相应功能时,都需要先验证用户权限,再显示相应权限范围内的信息。这样才能保证用户不会越权使用系统。

用户登录验证的方式很多,但想起来简单,做起来也不难,但做好似乎又不是那么容易。

这里就以一个简单的代码结构模拟用户登录及用户验证的结构。

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 完整代码

源码: 纯Python代码实现装饰器模式用户验证源码

4. 验证结果

4.1 验证步骤

4.1.1 数据初始化

1.引入代码文件
2.初始化用户信息
3.查看用户信息
  1. 引入代码文件:
import user_login as user
  1. 初始化用户信息
    此函数会创建一个文件到程序执行目录下,并且将程序里预设的用户信息写入新创建的文件中。
oUser = user.User()
oUser.OutToFile()
  1. 查看用户信息
    此函数从前面已创建的用户文件中读取数据,并打印的运行窗口。
oUser.ReadFromFile()

4.1.2 用户操作

1.用户登入
2.用户查看信息
3.用户登出
  1. 用户登入
    此函数为演示实际用户登录操作,只需要输入参数 user_name ,user_pass,即可完成账号验证操作,并返回登录是否成功提示信息。
@ValidUser
def Login(user_name, user_pass):
    print("用户%s登录成功" % (user_name,))
  1. 用户查看信息
    此函数演示验证用户权限范围,并且不能查看其它账号信息。如果验证是登录用户,则返回用户信息,反之则返回相应提示信息。
@ValidUser
def ViewUserInfo(user_name):
    u = staticmethod.user_list.get(user_name)
    print(u)
  1. 用户登出
    此函数为演示实际用户登出操作,只需要输入参数 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 总结

用户登录是一个很重要的部分,在实际工作中,其实预见的并不多,因为在工人中,多数情况是负责项目中的一个模块,很少预到登录模块。如果二次开发,或公司系统维护就可能性更小,因为这部分需要修改的机率很低。但是还是需要了解其工作方式。本文是以装饰器的方式。当然还有很多实现方式,要在实际项目中发现。


网站公告

今日签到

点亮在社区的每一天
去签到