增加数据展示、管理页面的安全访问。
之前在login向home跳转时,为进行账户验证,导致用户可以直接使用网址跳过登录,所有考虑在跳转时携带信息,在home页面验证携带的信息,如果未携带合法信息,则返回login。
原有跳转方式。
def login(request):
"""
登录页面
:param request:
:return: 账号验证无误则进入管理首页,有误则包含警告信息返回当前页
"""
unLogin = ''
# 调用数据库查询方法
rows = searchData.searchContents('users')
# 将数据库中获取的元组转为字典
users = {}
for row in rows:
users[row[0]] = row[1]
# 根据页面的访问方式进行响应
if request.method == 'GET':
if 'unLogin' in request.session:
unLogin = request.session['unLogin']
return render(request, 'login.html', {'unLogin': unLogin})
else:
username = request.POST.get('username')
password = request.POST.get('password')
if username in users and password == users[username]:
# 使用会话传递用户名
request.session['username'] = username
return redirect('/home')
return render(request, 'login.html', {'notice': '管理员账号或密码输入错误', 'unLogin': unLogin})
在view.py中修改login的代码,跳转至home时将用户名使用session存储。
def home(request):
"""
:param request:
:return: 首页
"""
# 获取users表中所有信息,判断跳转时携带的用户名是否正确。
# 调用数据库查询方法
rows = searchData.searchContents('users')
# 将数据库中获取的元组转为字典
users = {}
for row in rows:
users[row[0]] = row[1]
# 获取session中存放的用户名
username = request.session.get('username')
if username not in users:
request.session['unLogin'] = '您还未登录!'
return redirect('/login')
# 清除session防止影响其他功能
request.session.flush()
# 获取最新文件内容
os.system(r"C:\Users\12269\PycharmProjects\CMDB\web\tools\getClientData.py")
# 获取'web/clientData/dockerStatus.txt'内容,并进行过滤操作。
dockerStatus = []
try:
with open('web/clientData/dockerStatus.txt', 'r') as file:
# 将文件中内容转化成列表
for line in file:
data = ast.literal_eval(line)
dockerStatus.append(data)
# 删除每个子列表的第一个元素
for sublist in dockerStatus:
del sublist[0]
except FileNotFoundError:
print('文件 web/clientData/dockerStatus.txt 不存在!')
# 将dockerStatus列表中存储的信息传输至数据表
from web.models import DockerStatus
# 清空数据表
DockerStatus.objects.all().delete()
# 插入数据
for i in range(0, len(dockerStatus)):
obj = DockerStatus.objects.create(**{'name': dockerStatus[i][0], 'status': dockerStatus[i][1]})
obj.save()
# 从数据库中获取web_dockerstatus表的数据
rows = searchData.searchContents('web_dockerstatus')
dockerStatus = {}
for row in rows:
dockerStatus[row[1]] = row[2]
# 获取'web/clientData/allDockerStatus.txt'内容
servicesStatus = ''
try:
with open('web/clientData/allServicesStatus.txt', 'r') as file:
content = file.readlines()
servicesStatus = [line.replace('\n', '') for line in content] # 去除\n
except FileNotFoundError:
print('文件 web/clientData/allDockerStatus.txt 不存在!')
# 筛选allServicesStatus.txt中的有效数据,并存入web_allServicesStatus表中
from web.models import AllServicesStatus
# 清空数据表
AllServicesStatus.objects.all().delete()
did = ''
name = ''
for row in servicesStatus:
user = ''
pid = ''
ppid = ''
cpu = ''
elapsed = ''
tty = ''
if 'Container ID' in row:
did = row[-12:] # 获取容器ID
if 'Container Name' in row:
name = row[15:] # 获取容器名称
if 'USER' in row:
continue # 当遍历到表头行时跳过该行
if 'has no running processes' in row: # 当容器中不存在进程,则状态字段置空
obj = AllServicesStatus.objects.create(**{'did': did,
'name': name,
'user': user,
'pid': pid,
'ppid': ppid,
'cpu': cpu,
'elapsed': elapsed,
'tty': tty})
obj.save()
if 'pts' in row or '?' in row:
tempStatusList = re.split(r"\s+", row.strip()) # 按空格拆分行
print(tempStatusList)
user = tempStatusList[1] # 获取服务用户
pid = tempStatusList[2] # 获取服务pid
ppid = tempStatusList[3] # 获取服务ppid
cpu = tempStatusList[4] # 获取服务cpu使用率
elapsed = tempStatusList[5] # 获取服务运行时间
tty = tempStatusList[6] # 获取服务tty
# 填入数据
obj = AllServicesStatus.objects.create(**{'did': did,
'name': name,
'user': user,
'pid': pid,
'ppid': ppid,
'cpu': cpu,
'elapsed': elapsed,
'tty': tty})
obj.save()
# 从数据库获取数据。
servicesStatus = searchData.searchContents('web_allServicesStatus')
return render(request, 'home.html',
{'username': username, 'dockerStatus': dockerStatus, 'servicesStatus': servicesStatus})
view代码,从数据库获取用户名,并判断session中是否存在当前访问所使用的用户名。
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CMDB登录</title>
<link rel="stylesheet" href="{% static 'css/login.css'%}">
<script src="{% static 'js/login.js' %}"></script>
</head>
<body>
<div id="attention">
<img src="{% static 'img/网站设置.png'%}">
<b><i style="color: #1296db">欢迎来到CMDB管理中心</i></b>
<a href="/register/" id="register">申请账户</a>
</div>
<div style="height: 100vh" id="back"></div>
<p id="unLoginNotice">{{ unLogin }}</p>
<form method="post" id="loginBlock">
<img src="{% static 'img/管理员_角色管理.png' %}" alt="图片丢失">
<span id="loginTitle">
管理员登录
</span>
<input type="text" placeholder="请输入管理员账号" name="username">
<br>
<input type="password" placeholder="请输入密码" name="password">
<br>
<span style="font-size: 10px;color: red">{{ notice }}</span>
<br>
<input type="submit" id="sub" title="登录">
</form>
</body>
</html>
login中添加违规跳转时返回的提示信息的处理部分。
*{
margin: 0;
padding: 0;
}
#attention{
height: 40px;
line-height: 40px;
font-size: 20px;
align-items: center;
padding-left: 60px;
overflow: hidden;
}
#attention>img{
position: absolute;
top: 6px;
left: 20px;
height: 30px;
width: 30px;
}
#register{
font-size: 10px;
margin-left: 70%;
}
#unLoginNotice{
position: absolute;
top: 80px;
left: 650px;
color: red;
font-size: 30px;
}
form{
border-radius: 5px;
border: 1px solid grey;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 400px;
padding: 10px;
padding-right: 20px;
align-content: center;
background-color: white;
}
form>img{
display: inline-block;
height: 20px;
width: 20px;
}
#loginTitle{
display: inline-block;
color: #1296db;
position: relative;
top: -4px;
left: 5px;
}
input{
border-radius: 5px;
margin: 5px 0;
width: 100%;
height: 30px;
line-height: 30px;
padding-left: 5px;
border: 1px solid lightgrey;
}
#sub{
width: 405px;
}
#subImg{
height: 15px;
width: 15px;
}
login样式。
window.onload = function (){
//获取元素
const loginBlock = document.getElementById('loginBlock');
const back = document.getElementById('back');
const unLoginNotice = document.getElementById('unLoginNotice')
//form的鼠标点击事件
loginBlock.addEventListener('click', function() {
//form的单击响应事件,使back盒子设置为蓝色半透明,实现聚焦效果
back.style.background = '#1296db';
back.style.opacity = '0.5';
//隐藏unLoginNotice
unLoginNotice.style.display = 'none';
});
//form的鼠标移出事件
loginBlock.addEventListener('mouseleave',function (){
back.style.background = 'white';
back.style.opacity = '0';
});
}
行为js。
后续页面将采用相同或相似的处理方式。