下面写三种方法来实现,用户在规定时间内,输入次数上限,封禁账号的功能。
第一种:使用redis完成用户封禁状态
第二种:使用mysql
第三种:使用文件
1.封禁用户流程图
第一种方法: Redis实现
# 声明登录方法
# @check_imgcode
async def get(self):
email = self.get_argument('email', None)
password = self.get_argument('password', None)
print(password)
num_mysql = None
# 读取数据库
try:
# 获取计数器(redis)
num = self.application.redis.get("num_"+email)
# # 如果存在
if num:
if int(num) > 5:
self.finish({'msg': '您已超过错误次数', "errcode": 3})
user = await self.application.objects.get(
UserModel.select().where((UserModel.email == email) & (UserModel.password ==
make_password(password))))
# 判断用户状态
if user.state == 0:
self.finish({'msg': '请激活您的邮箱', 'email': user.email, "errcode": 2})
else:
# 生成jwt
myjwt = MyJwt()
self.finish({'msg': '登陆成功', "token": myjwt.encode({'uid': user.id}), 'email': user.email, "errcode": 0})
except Exception as e:
return self.finish({'msg':'用户名或者密码错误',"errcode":1})
第二种方法:Mysql来实现
首先要建表:
# 基类
class BaseModel(peewee.Model):
id = peewee.IntegerField(primary_key=True, unique=True, constraints=
[peewee.SQL('AUTO_INCREMENT')])
# 入库时间
create_time = peewee.DateTimeField(default=datetime.now,
help_text="入库时间")
# 重写父类方法
def save(self, *args, **kwargs):
# 判断什么时候赋值入库方法
if self._pk is None:
# 赋值
self.create_time = datetime.now()
return super(BaseModel, self).save(*args, **kwargs)
class Meta:
# 传递数据库连接
database = database
# 计数器
class CheckNumModel(BaseModel):
email = peewee.CharField(null=False, unique=True, max_length=100)
num = peewee.IntegerField(null=False, default=0)
class Meta:
# 声明表明
db_table = "checknum"
然后在声明方法:
# 声明登录方法
# @check_imgcode
async def get(self):
email = self.get_argument('email', None)
password = self.get_argument('password', None)
print(password)
num_mysql = None
# 获取计数器mysql版本
try:
num_mysql = await self.application.objects.get(CheckNumModel.select().where
(CheckNumModel.email == email))
res = FileHandel().check(email + '.txt')
print(res)
if res == False:
return self.finish({'msg': '输入错误次数过的,请稍后再试!', 'errcode': 203})
if num_mysql:
print(num_mysql)
# 获取当前时间
now_time = int(time.time())
# 获取首次输错密码的时间点
num_time = num_mysql.create_time.timestamp()
# 减法运算
mytime = now_time - num_time
if mytime <= 30:
# 判断计数器
if num_mysql.num >= 5:
return self.finish({'msg': '账号已被封禁,请30分钟再试', "errcode": 5})
else:
# 清除计数器
await self.application.objects.delete(num_mysql)
user = await self.application.objects.get(
UserModel.select().where((UserModel.email == email) & (UserModel.password ==
make_password(password))))
# 判断用户状态
if user.state == 0:
self.finish({'msg': '请激活您的邮箱', 'email': user.email, "errcode": 2})
else:
# 生成jwt
myjwt = MyJwt()
self.finish({'msg': '登陆成功', "token": myjwt.encode({'uid': user.id}), 'email': user.email, "errcode": 0})
except Exception as e:
mysql逻辑
if num_mysql:
num_mysql.num = num_mysql.num + 1
# # 修改数据库
await self.application.objects.update(num_mysql)
else:
# 插入计数器,首次输错密码
await self.application.objects.create(CheckNumModel, email=email, num=1)
return self.finish({'msg':'用户名或者密码错误',"errcode":1})
第三种:文件实现账号封禁
import os
import json
import time
class FileHandel:
# 逻辑判断
def check(self,filename):
if self.find(r"./",filename):
text = self.read(filename)
# 转换
text = json.loads(text)
now_time = int(time.time())
# 获取首次输错密码的时间
num_time = text["time"]
# 减法运算
mytime = now_time - num_time
if mytime <= 30:
# 判断计数器
if text["num"] >5:
return False
else:
self.delfile(filename)
else:
self.write(filename)
# 删除文件
def delfile(self,filename):
if os.path.exists(filename):
os.remove(filename)
# 读文件
def read(self,filename):
text = ""
with open(filename,'r',encoding='utf-8') as f:
text = f.read()
return text
# 写文件
def write(self,filename):
res = self.find(r"./",filename)
if res:
# 读
text = self.read(filename)
# 累加
text = json.loads(text)
text["num"] +=1
with open(filename,"w",encoding="utf-8") as f:
f.write(json.dumps(text))
else:
mytime = int(time.time())
text = '{"time":%s,"num":1}' % mytime
with open(filename,"w",encoding="utf-8") as f:
f.write(text)
# 查找文件
def find(self,start,filename):
for relpath,dirs,files in os.walk(start):
if filename in files:
return True
else:
return None
# 声明登录方法
# @check_imgcode
async def get(self):
email = self.get_argument('email', None)
password = self.get_argument('password', None)
print(password)
num_mysql = None
# 读取数据库
# try:
# 获取计数器(redis)
# num = self.application.redis.get("num_"+email)
# # 如果存在
# if num:
# if int(num) > 5:
# self.finish({'msg': '您已超过错误次数', "errcode": 3})
# 获取计数器mysql版本
try:
# num_mysql = await self.application.objects.get(CheckNumModel.select().where
# (CheckNumModel.email == email))
res = FileHandel().check(email + '.txt')
print(res)
if res == False:
return self.finish({'msg': '输入错误次数过的,请稍后再试!', 'errcode': 203})
if num_mysql:
print(num_mysql)
# 获取当前时间
now_time = int(time.time())
# 获取首次输错密码的时间点
num_time = num_mysql.create_time.timestamp()
# 减法运算
mytime = now_time - num_time
if mytime <= 30:
# 判断计数器
if num_mysql.num >= 5:
return self.finish({'msg': '账号已被封禁,请30分钟再试', "errcode": 5})
else:
# 清除计数器
await self.application.objects.delete(num_mysql)
user = await self.application.objects.get(
UserModel.select().where((UserModel.email == email) & (UserModel.password ==
make_password(password))))
# 判断用户状态
if user.state == 0:
self.finish({'msg': '请激活您的邮箱', 'email': user.email, "errcode": 2})
else:
# 生成jwt
myjwt = MyJwt()
self.finish({'msg': '登陆成功', "token": myjwt.encode({'uid': user.id}), 'email': user.email, "errcode": 0})
except Exception as e:
# mysql逻辑
# if num_mysql:
# num_mysql.num = num_mysql.num + 1
# # # 修改数据库
# await self.application.objects.update(num_mysql)
# else:
# # 插入计数器,首次输错密码
# await self.application.objects.create(CheckNumModel, email=email, num=1)
# # redis逻辑
# if num:
# # 累加操作
# self.application.redis.incr('num_'+email)
# else:
# self.application.redis.setex('num_'+email,30,1)
#
#
# 文件计数器
FileHandel().write(email+'.txt')
return self.finish({'msg':'用户名或者密码错误',"errcode":1})