给Django添加用户登录登出界面

我的Django运维平台很不幸的被公司安全系统扫描出来了,给了我一个超级大警告。主要也怪我当时偷懒,只是在SLB层面做了IP访问限制但是没有给服务器nginx里做白名单,所以网站是可以通过“IP地址加端口”访问的。恰巧ping里面用了一个AES加解密的脚本,那个算法有问题,可以获取当前用户的权限,我特么的还是直接用root启动的nginx,而且这个机器里面还有ansible,当然后果很严重。

出了问题,不能消极对待而要积极解决,于是要先给网站做一个完善的用户登录鉴权系统。再一次背景介绍:
python:3.6.5
Django:2.1.1
Project:Kubernetes,文件夹路径就是/django/Kubernetes/
App:createyaml,文件夹路径就是/django/Kubernetes/createyaml

实现用户登录鉴权

首先,先编写一个index.html的页面做登录界面,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>请先登录</title>
<link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css"> #引入css样式
<link rel="icon" href="/static/pic/batman.ico" type="image/x-icon"> #引入一个标签图
</head>
<body background="/static/pic/easyplane.jpg"> #背景图片设置
<div style="margin-top: 200px">
<div style="text-align:center;">
<font color='brown'><h1>请输入您的账号密码</h1></font>
<div>
<div>
<form class="ui form" method="post" action="">
<div class="field">
<input type="text" name="username" placeholder="username"><br>
</div>
<div class="field">
<input type="password" name="password" placeholder="password"><br>
</div>
<font color=red>{{ error }}</font><br> #登录错误红色表示
<button class="btn btn-default" type="submit">登陆</button>
{% csrf_token %}
</form>
</div>
</div>
</div>
</div>
</body>
</html>

效果如下:
akb48

在Kubernetes这个app文件夹里的urls.py里给这个鉴权网站添加一个路由:

1
2
3
4
5
6
7
8
9
10
from django.contrib import admin
from django.urls import path,include
from . import views

urlpatterns = [
path('',views.login_action,name='login'), #首页就是login_action的函数
path('homepage.html',views.home,name='home'), #将原来的首页改成叫homepage.html
path('admin/', admin.site.urls),
...其余省略
]

在同级的views.py里编写login_action函数,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from django.shortcuts import render,render_to_response
from django.http import HttpResponse,HttpResponseRedirect
from django.contrib import auth

#登陆
def login_action(request):
if request.method == 'POST': #通过post形式获取,get的话会在地址栏里看到账号密码
username = request.POST.get('username', '')
password = request.POST.get('password', '')
user = auth.authenticate(username=username, password=password) #使用django自带方式鉴权
if user is not None:
auth.login(request, user) # 登录
request.session['user'] = username # 将session信息记录到浏览器
response = HttpResponseRedirect('homepage.html') #鉴权OK就跳转到homepage.html
return response
else:
return render(request,'index.html', {'error': '账号密码有误,请联系管理员!'})
else:
return render(request,'index.html')

#首页
def home(request):
context = {}
return render_to_response('homepage.html',context)

登陆的用户/密码就是django后台的账号/密码,可以用superuser来登陆。保存文件之后,系统会重启django,查看效果如图:
akb48

render和render_to_response的区别

上面的login_action函数里,用了renderrender_to_response,如果只用render_to_response,同时把所有的render改成render_to_response,那么在访问首页的时候就会出现TemplateDoesNotExist at /这样的错误:
akb48

明明他俩都是用来展示模板页面的。为什么会有模板不存在这样?原因是render_to_response()的第一个参数必须是要使用的模板名称。如果要给定第二个参数,那么该参数必须是为该模板创建Context时所使用的字典。如果不提供第二个参数,render_to_response()使用一个空字典。而render第一个参数可以是request。

所以如果都要用render_to_response,那么就要改成如下:

1
2
3
4
else:
return render_to_response('index.html', {'error': '账号密码有误,请联系管理员!'},context_instance=RequestContext(request))
else:
return render_to_response('index.html')

但是这样的话,可能在登录的时候就会有csrf的错误,需要把csrf去掉。

实现登出功能

有了登录还得有登出,还是老套路,先编写路由如下:

1
path(r'logout/', views.logout,name="logout"),

然后对应去views.py里写logout这个函数:

1
2
3
4
5
6
from django.http import HttpResponseRedirect
from django.contrib import auth #引入django默认的auth功能
#注销
def logout(request):
auth.logout(request)
return HttpResponseRedirect('/login') #跳转到登录页/login

然后就是在首页里添加一个登出的链接,链接指向就是/logout/。测试一下效果:
akb48

参考资料

http://www.nowamagic.net/academy/detail/1318431

感谢您请我喝咖啡~O(∩_∩)O,如果要联系请直接发我邮箱chenx1242@163.com,我会回复你的
-------------本文结束感谢您的阅读-------------