大家好,这里是<测试开发实战-手把手系列之五>
直接开始!
新建user(用户)应用,过程应该不需要说了
我们来看看view.py的新增方法(InsertRecord)
#新增
class InsertRecord(View):
def post(self, request):
dto = json.loads(request.body)
username = dto.get("username","")
password = dto.get("password", "")
name = dto.get("name", "")
status = dto.get("status", "")
Record = userModel(username=username,password=password,name=name,status=status)
Record.save()
return HttpResponse(json.dumps({"code":20000,"message":"成功"}),content_type="application/json")
初看起来没问题,但我们想想,用户的用户名是不是应该唯一。
数据唯一性的限制一般可以在2方面,一个是数据库做字段唯一性校验,一个是代码层面限制唯一性。
数据库的我们不管,我们来看看代码的限制唯一性。
逻辑其实很简单,获取前端请求的username,看username在数据库中存不存在即可。
我们创建一个函数来专门判断唯一性,函数关键字(def)
def duplicateVerify(str):
Record = userModel.objects.filter(username=str).first() #获取查询结果的第一条,否则返回None
if Record is not None: #判断是否为None
return False
else:
return True
重点:
1、first()方法:返回查询的第一个,如果没有找到返回None
2、is not:不等于。is比较的是对象的内存地址,而==比较的是对象的内容。这2个是有区别的,面试可能会考
3、None:None是一个单例对象,即只要是None,那么他们的内存地址是一样的
我们优化下新增代码
class InsertRecord(View):
def post(self, request):
dto = json.loads(request.body)
username = dto.get("username","")
password = dto.get("password", "")
name = dto.get("name", "")
status = dto.get("status", "")
if (duplicateVerify(username)):
Record = userModel(username=username, password=password, name=name, status=status)
Record.save()
return HttpResponse(json.dumps({"code": 20000}), content_type="application/json")
else:
return HttpResponse(json.dumps({"code": 10002, "message": "用户名重复"}), content_type="application/json")
这样就完成了用户名唯一性校验,是不是这样就完了呢,当然不是,毕竟这一节一半都没写到。众所周知用户登录是需要密码的,看看上面代码,直接是以明文方式存取的,这样就暴露了。
OK,到了这里,就来到本节重头了,我们要对密码进行加密。加密的方式有多种:DES\MD5\AES等,选一个适合的,我选AES。AES有几种加密模式,我们用基础的ECB模式。
安装方法:pip安装pycryptodome
在view.py中添加函数,代码如下:
#补足字符串长度为16的倍数
def add_to_16(value):
while len(value) % 16 != 0: #len()获取字符串长度
value += '\0'
return str.encode(value) #字符串str转字节bytes
#加密方法
def Encrypted_text(text):
key = '1234567890123456' # # 密钥长度必须为16、24或32位,分别对应AES-128、AES-192和AES-256
aes = AES.new(add_to_16(key), AES.MODE_ECB) # 初始化加密器,本例采用ECB加密模式
encrypted_text = str(base64.encodebytes(aes.encrypt(add_to_16(text))), encoding='utf8').replace('\n', '') # 执行加密并转码返回str
return encrypted_text
#解密方法
def decrypt_oralce():
key = '1234567890123456'
aes = AES.new(str.encode(key), AES.MODE_ECB) # 初始化加密器,本例采用ECB加密模式
decrypted_text = str(
aes.decrypt(base64.decodebytes(bytes(passwod_text, encoding='utf8'))).rstrip(b'\0').decode("utf8")) # 解密
return decrypted_text
重点:
1、加密的几种方法DES\MD5\AES\RSA面试可能会问
2、len()方法:获取字符串长度
3、str.encode()方法将字符串str转字节bytes。关于python的字符编码可以百度学习掌握
4、AES的加密模式,除了ECB之外,其他的都需要一个初始化向IV。AES加密数据块分组长度必须为128比特
5、replace(’\n’, ‘’)方法:把字符串中的 旧字符串 替换成新字符串
6、base64:encodebytes对字节型数据进行编码,decodebytes解码为字节型数据
7、str(),bytes():强制转换为str类型和bytes类型,这是python的内置函数,python的内置函数还算比较重要,面试可能会考。
我们优化InsertRecord代码:
class InsertRecord(View):
def post(self, request):
dto = json.loads(request.body)
username = dto.get("username","")
password = dto.get("password", "")
password = Encrypted_text(password)
name = dto.get("name", "")
status = dto.get("status", "")
if (duplicateVerify(username)):
Record = userModel(username=username, password=password, name=name, status=status)
Record.save()
return HttpResponse(json.dumps({"code": 20000}), content_type="application/json")
else:
return HttpResponse(json.dumps({"code": 10002, "message": "用户名重复"}), content_type="application/json")
这样就将用户名和密码的密文写入数据库了
接下来我们新增一个登录的接口,用于用户的登录校验
#登录接口
class Login(View):
def post(self,request):
dto = json.loads(request.body)
username = dto.get("username")
password = dto.get("password")
recordList = userModel.objects.values().filter(Q(username=username)&Q(password=Encrypted_text(password)))
if len(recordList)>0:
return HttpResponse(json.dumps({"data": list(recordList), "code": 20000},cls=DateEncoder), content_type='application/json')
return HttpResponse(json.dumps({"message":"用户名或密码不对","code":10002}), content_type='application/json')
应该很好理解了,根据前端传的用户名和加密的密码进行查询,查到了结果,正确返回。否则返回"用户名或密码不对"
最后,别忘了在urls.py中设置接口访问路径
总结
本节介绍了自定义函数的写法和调用,字符串AES加密,并新增一个Login接口
演示代码:
https://github.com/danzi516/TestDev/tree/main/%E6%89%8B%E6%8A%8A%E6%89%8B/5/myproject
更多文章,关注一波,谢!