1. 程式人生 > >django中session和cookie

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資料。