用户的登录两种方式:
- 使用login()和logout()这两个内置函数实现登录和退出;缺点就是用户的登录是在操作同一个request.user,导致同一台电脑不能同时登录两个用户;
- 如果同一台电脑的同一个网站,登录多个账号,为了防止串号,不能再使用login()和logout()函数了,可以通过session和cookie来实现这个需求;
我们可以发现,第一种方式,如果用之前的那种login()和logout()的方式进行登录和退出,当用用户test登录前端页面,同时使用admin超级管理员登录admin后台。这是你再去刷新用户test登录的前端页面,用户就会由test变成admin。 这样,就不能登录多个账号,那么我们今天就学习使用第二种方式:就涉及到了cookie和session。
django中的cookie和session:
- 用户在前端登录以后,此时django会在django_session这个表中,生成一个键值对:session_key和session_data;
其中,session_key是用于在响应中通过Set-Cookie字段返回给浏览器,浏览器会将这个session_key(sessionid)的值存储到本地; - 等用户登录完以后,在访问其它页面的时候,浏览器就会将这个本地cookie中的sessionid这个键的值,放在请求头中,交给后台django,django在接收到这个sessionid值的时候,会利用这个值向表django_session获取session_data的值,进而判断用户是否处于登录状态;
- session_data的值是利用用户名+密码生成的一个加密字符串,这个字符串就是用来表明用户的登录状态,如果用户登录成功,那么django_session就会生成一个session_data;用户没有登录成功,是不会有session_data数据的。
session的过期时间:django默认设置是2周。如果session过期,浏览器再携带之前的cookie就不能免登录了,因为cookie已经失效了。
前端:如果超出了session的过期时间,那么浏览器会自动将对应的cookie删除掉;
后端:django没有对过期的session做任何处理;
如何删除后台保存的一些过期的session信息:
执行命令:python manage.py clearsessions
如果用户在过期时间内主动退出登录,那么django会将该用户对应的session数据给删除掉(request.session.flush())。
但是如果用户在登录完以后没有主动退出,并且超出了过期时间,用户需要重新登录,但是django中的过期session是不会被清理的。需要定期清理过期的session数据。
那么,接下来我们就开始吧。
首先,创建一个APP:cookie_session ,在urls.py文件中绑定路由
from django.contrib import admin
from django.urls import path
from cookie_session import views
urlpatterns = [
path('admin/', admin.site.urls),
path('login/', views.login_fun),
path('index/', views.index),
path('logout/', views.logout_fun),
path('register/', views.register)
]
登录的功能:
此次,加入了一个单选框,在登录的时候,问是否记住用户名,方便下次登录,输入框自动显示用户名
在views.py中:
def login_fun(request):
if request.method == 'GET':
# 每次在登录的时候,都要去cookie中获取username的值。
name = request.COOKIES.get('username', '')
return render(request, 'login.html', {'name': name})
elif request.method == 'POST':
uname = request.POST.get('username')
upassword = request.POST.get('password')
user = UserModel.objects.filter(uname=uname, upassword=upassword)
if user:
# 用户名密码都正确。
# 需要判断用户是否勾选了 "记住用户名",如果勾选了,可以将这个用户名保存到浏览器的cookie中,并且可以设置过期时间。cookie一旦被浏览器缓存,除非cookie过期了,cookie不会受到项目的是否运行的影响。
is_jizhu = request.POST.get('box')
response = HttpResponseRedirect('/index/')
if is_jizhu:
# 用户选择了记住,后台如何向前端传递cookie? 响应头中的Set-Cookie
# sessionid的过期时间,是session的过期时间,默认是两周。
# 但是username这个cookie是自己在响应头中添加的,跟session没有关系,所以这种自己添加的cookie信息的过期时间默认都是 "浏览器会话结束时",也就是浏览器关闭之后,cookie就过期了。可以通过max_age来设置cookie的过期时间。
response.set_cookie('username', uname, max_age=1900000)
else:
# 如果用户没有勾选记住。将username这个cookie置为空。
response.set_cookie('username', '')
# 在向浏览器返回cookie的同时,也需要向后台表django_session中添加用户的登录状态session_data.
request.session['username'] = uname
return response
else:
return render(request, 'login.html', {'error': '用户名或密码错误'})
def index(request):
return render(request, 'index.html')
在login.html中:
<body>
<form action="/login/" method="post">
{% csrf_token %}
<input type="text" placeholder="账号" name="username" value="{{ name }}"><br>
<input type="text" placeholder="密码" name="password"><br>
{# 添加一个是否记住用户名的功能。以后再登录这个网站,用户名自动填充。 #}
{# type="checkbox" 分勾选和不勾选,勾选值为1,不勾选值为0. #}
记住用户名:<input type="checkbox" name="box" value="1" checked><br>
<button type="submit">登录</button>
</form>
</body>
退出的功能:
views.py中:
def logout_fun(request):
# 如果用户退出,需要将登录时生成的session信息删除,等用户再次登录的时候,需要重新生成session.
request.session.flush()
return redirect('/index/')
注册的功能:
views.py中:
def register(request):
if request.method == 'POST':
if request.is_ajax():
# is_ajax()这个方法是用于区分这个POST请求是否是ajax发送的POST请求。因为form表单也能发送POST请求。
name = request.POST.get('username')
pwd = request.POST.get('password')
user = UserModel(uname=name, upassword=pwd)
user.save()
return HttpResponse('ok')
注册没有写页面,就在首页中发送固定的用户名和密码了
index.html中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
{% if request.session.username %}
{# 通过去session中获取username(request.session['username'] = uname) 如果能够获取到,说明用户登录了。反之就是没有登录。#}
<h1>用户:{{ request.session.username }}</h1>
<p>成功登录并进入首页。。。</p>
<a href="/logout/">退出</a>
{% else %}
<a href="/login/">登录</a>
<a href="#" id="register">注册</a>
{% endif %}
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<script>
{# $.ajaxSetup可以对所有的ajax请求进行全局配置的方法。 #}
$.ajaxSetup({
data:{
'csrfmiddlewaretoken': '{{ csrf_token }}'
}
});
$('#register').click(function(){
$.ajax({
url: '/register/',
type: 'POST',
data: {
'username': 'zhangsan',
'password': '123456'
},
success: function(data, status){
{# ajax 发送请求之后,如果需要重定向,views.py就不能进行重定向了,需要让ajax进行重定向。 #}
if (data == 'ok'){
window.location.href = '/login/';
}else{
alert('失败');
}
}
})
})
</script>
</body>
</html>
先点击注册,注册一个账号zhangsan
然后进行登录
如果选择记住用户名。再次登录的话,直接填充用户名
因为,用户名已经加载到了本地。打开浏览器的设置->高级->内容设置->cookie->查看所有cookie和网站数据->localhost或者127.0.0.1
会看到有保存到本地的username