django中session和cookie
使用者的登入兩種方式: ①使用login()和logout()這兩個內建函式實現登入和退出:缺點就是使用者的登入是在操作同一個request.user,導致同一臺電腦不能同時登入兩個使用者。 ②如果同一臺電腦的同一個網站,登入多個賬號,為了防止串號,不能再使用login()和logout()函式,可以通過session和cookie來實現這個需求。
1.models.py檔案
from django.db import models class UserModel(models.Model): uname=models.CharField(max_length=20) upassword=models.CharField(max_length=50)
在settings.py檔案
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME':'cookie',
'HOST':'localhost',
'USER':'root',
'PASSWORD':'123456'
}
}
在資料庫中新建資料庫cookie,並執行命令同步資料。 2.在views.py檔案
from django.shortcuts import render,redirect,HttpResponseRedirect from .models import UserModel 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 #在響應頭response中設定cookie:{'username':uname} response.set_cookie('username',uname) 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')
redirect():返回值是HttpResponseRedirect類的物件,這個函式只能給前端返回一個Response,不能修改Response,比如響應頭,響應狀態等。 HttpResponse:只能返回一個文字內容的Response物件。該類是可以設定響應頭的。 HttpResponseRedirect:該類既可以設定響應頭,又有重定向的功能。
3.在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), ]
4.在templates資料夾下新建: login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登入頁面</title>
</head>
<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'分勾選和不勾選,勾選value="1",加上checked。如果不勾選值為0 #}
記住使用者名稱:<input type="checkbox" name="box" value="1" checked><br>
<button type="submit">提交</button>
</form>
</body>
</html>
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首頁</title>
</head>
<body>
{# 通過在session中獲取username(request.session['username']=uname)如果能夠獲取到,說明使用者登入了,反之就是沒有登入。 #}
{% if request.session.username %}
<h1>使用者:{{ request.session.username }}</h1>
<p>成功登入並進入首頁。。。。</p>
<a href="/logout/">退出</a>
{% else %}
<a href="/login/">登入</a>
<a href="#">註冊</a>
{% endif %}
</body>
</html>
過程: 1.使用者在前端登入以後,此時django會在django_session這個表中,生成一個鍵值對:session_key和session_data; 其中,session_key是用於在響應中通過Set-Cookie欄位返回給瀏覽器,瀏覽器會將這個session_key(sessionid)的值儲存到本地。 2.等使用者登入完以後,在訪問其他頁面的時候,瀏覽器就會將這個本地cookie中的sessionid這個鍵的值,放在請求頭中,交給後臺django,django在接收到這個sessionid值的時候,會利用這個值向表django_session獲取session_data的值,進而判斷使用者是否處於登入狀態。
小知識點: ①在settings.py檔案中配置過期時間:(單位是秒) SESSION_COOKIE_AGE=10
②session的過期時間:django預設設定是2周。如果session過期,瀏覽器再攜帶之前的cookie就不能免登入了,因為cookie已經失效了。 瀏覽器(前端):如果超出了session的過期時間,那麼瀏覽器會自動刪除過期cookie。 後端:django沒有對過期的session做任何處理,還依然存在於表中。
③如何刪除後臺儲存的一些過期的session資訊: (管理員手動清除)執行命令:python manage.py chearsessions
④如果使用者在過期時間內主動退出,那麼django會將該使用者的session資料給刪除掉(request.session.flush()).但是如果使用者在登入完以後沒有主動退出,並且超出了過期時間,使用者需要重新登入,但是django中的過期session是不會被清理的。需要定期清理過期的session資料。