Django 實(shí)戰(zhàn)2:利用 Session 實(shí)現(xiàn)自動登錄

題圖:by thefolkpr0ject from Instagram

上篇文章中講到 Django 如何啟動以及配置 sessions 功能。sessions 功能用是跟蹤用戶的狀態(tài),經(jīng)常結(jié)合 Cookie 功能實(shí)現(xiàn)自動登錄功能。 所謂的“自動登錄”指的是:我們登錄一些網(wǎng)站,在不關(guān)閉瀏覽器以及距離上次登錄時(shí)間不是很長的情況下。無論我們在新的標(biāo)簽頁打開網(wǎng)站,還是關(guān)閉頁面重新打開網(wǎng)站,登錄狀態(tài)一直保持著。本文內(nèi)容有兩個(gè):一是利用 Django 實(shí)現(xiàn)自動登錄功能,二是揭開“自動登錄”的神秘面紗。

1 新建項(xiàng)目

我為了將本系列所有文章的示例代碼保持集中狀態(tài),所以直接在 Django_demo 項(xiàng)目中創(chuàng)建應(yīng)用。如果第一次看這文章,需要先創(chuàng)建項(xiàng)目(project),再創(chuàng)建應(yīng)用(app)。我新建的應(yīng)用是 demo_session

點(diǎn)擊查看大圖

然后在 setting.py 中啟動請用,并檢查 sessions 組件是否啟動。


點(diǎn)擊查看大圖

因?yàn)樾枰?Cookie 功能,所以同樣需要在 settings.py 增加一些配置。

SESSION_COOKIE_NAME = "sessionid"       # Session的cookie保存在瀏覽器上時(shí)的key
SESSION_COOKIE_PATH = "/"               # Session的cookie保存的路徑(默認(rèn))
SESSION_COOKIE_DOMAIN = None            # Session的cookie保存的域名(默認(rèn))
SESSION_COOKIE_SECURE = False           # 是否Https傳輸cookie
SESSION_COOKIE_HTTPONLY = True          # 是否Session的cookie只支持http傳輸(默認(rèn))
SESSION_COOKIE_AGE = 1209600            # Session的cookie失效日期(2周)(默認(rèn))
SESSION_SAVE_EVERY_REQUEST = False      # 是否設(shè)置關(guān)閉瀏覽器使得Session過期
SESSION_COOKIE_AT_BROWSER_CLOSE = False  # 是否每次請求都保存Session,默認(rèn)修改之后才能保存

如果你將 SESSION_SAVE_EVERY_REQUEST 設(shè)置為 True, 那么關(guān)閉瀏覽器之后,需要重新登錄。

2 流程

應(yīng)用中會涉及到 3 個(gè)頁面,所以我繪制流程圖幫助理解。


點(diǎn)擊查看大圖

3 實(shí)現(xiàn)

3.1 新建 model

服務(wù)器接收到瀏覽器傳送過來登錄信息,需要驗(yàn)證賬號和密碼等信息。所以需要新建 model 保存信息,以便后續(xù)跟數(shù)據(jù)庫做校驗(yàn)。這里我只是簡單保存信息,登錄驗(yàn)證后續(xù)講解。

class User(models.Model):
    username = models.CharField(max_length=20)  # 賬號
    password = models.CharField(max_length=20)  # 密碼
    nickname = models.CharField(max_length=20)  # 昵稱

3.2 新建 form

用戶將登錄信息發(fā)送給服務(wù)器是用到 POST 請求,所以需要創(chuàng)建表單。在應(yīng)用目錄下新建名為 forms 目錄,然后創(chuàng)建 forms.py 文件。

from django.forms import ModelForm, TextInput, PasswordInput
from demo_session.models import User

class UserForm(ModelForm):
    class Meta:
        model = User
        fields = ['username', 'password', ]  # 只顯示 model 中指定的字段
        # 指定呈現(xiàn)樣式字段、指定 CSS 樣式
        widgets = {
            'username': TextInput(attrs={'class': 'text',
                                         'value': 'monkey'}),
            'password': PasswordInput(attrs={'value': '13245678', })
        }

3.3 新建視圖

頁面一共有三個(gè),分別是登錄、首頁、登出。具體實(shí)現(xiàn)如下:

# view.py
from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import render
from demo_session.form.forms import UserForm

# 用戶登錄
def login_view(request):
    # 過濾 POST 方法的請求
    if request.method == 'POST':
        userfrom = UserForm(request.POST)
        # 驗(yàn)證表單
        if userfrom.is_valid():
            username = userfrom.cleaned_data['username']
            password = userfrom.cleaned_data['password']
            # ... 執(zhí)行驗(yàn)證登錄信息操作

            # 將等你信息傳遞給 Session 對象, 實(shí)際應(yīng)用中不建議這么操作
            request.session['username'] = username
            # 跳轉(zhuǎn)到頁面
            return HttpResponseRedirect('/index/')
    else:
        # 不是 GET 請求則顯示表單
        userfrom = UserForm()
    template_view = 'login.html'
    return render(request, template_view, {'userfrom': userfrom})

# 成功登錄之后, 跳轉(zhuǎn)首頁
def index_view(request):
    username = request.session.get('username', '')
    # print(username)
    template_view = 'index.html'
    return render(request, template_view, {'username': username})

# 登出操作
def logout_view(request):
    # 刪除 session
    del request.session['username']
    return HttpResponse('登出成功')

3.4 對應(yīng)模板

視圖 login_view, index_view 對應(yīng)的模板是 login.html, index.html。
其中 login.html 的實(shí)現(xiàn)如下:

{% load staticfiles %}
<!DOCTYPE html>
<html lang="{{ LANGUAGE_CODE|default:"en-us" }}">
<head>
    <meta charset="UTF-8">
    <title>登錄</title>
    <link href="{% static 'css/style.css' %}" rel="stylesheet" type='text/css' >
    <!--webfonts-->
    <link href="{% static 'css/font.css' %}" rel='stylesheet' type='text/css'>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script type="application/x-javascript">
            addEventListener("load", function() { setTimeout(hideURLbar, 0); }, false);
            function hideURLbar(){ window.scrollTo(0,1); }</script>
</head>
<body>
    <div class="main">
        <div class="login-form">
        <h1>Member Login</h1>
            <div class="head">
                <img src="{% static 'images/user.png' %}" alt=""/>
            </div>
            <form action="" method="POST">
                {% csrf_token %}
                {{ userfrom.username }}
                {{ userfrom.password }}
                <div class="submit"><input type="submit" value="login" ></div>
                <p><a href="#">Forgot Password ?</a></p>
            </form>
        </div>
    </div>
</body>
</html>

index.html 的實(shí)現(xiàn)如下:

<!DOCTYPE html>
<html lang="{{ LANGUAGE_CODE|default:"en-us" }}">
<head>
    <meta charset="UTF-8">
    <title>首頁</title>
</head>
<body>
    <div >
        <h3>歡迎 {{username}} 到來~</h3>
        <div class="submit"><a href="/logout"><input type="submit" value="退出登錄" ></a></div>
    </div>
</body>
</html>

3.5 配置路由

最后一步,在 urls.py 中配置訪問路徑:

from demo_session.views import login_view, index_view, logout_view

urlpatterns = [
    # demo_session
    path('login/', login_view, name='login'),
    path('index/', index_view, name='index'),
    path('logout/', logout_view, name='index'),
]

4 實(shí)現(xiàn)效果

用戶訪問 http://127.0.0.1/login 進(jìn)行登錄操作。

點(diǎn)擊查看大圖

當(dāng)點(diǎn)擊 login 成功之后,會跳轉(zhuǎn)到首頁,首頁會顯示用戶名。同時(shí),Cookie 中多了一個(gè) sessionid 的字段。這字段名就是我們在 setttings.py 定義的。

點(diǎn)擊查看大圖

查詢數(shù)據(jù)庫 django_session 表的內(nèi)容,會多出一條數(shù)據(jù)。


點(diǎn)擊查看大圖

表中的字段含義如下:

  • session_key: 就是服務(wù)器給用戶返回的id。在瀏覽器當(dāng)中,這個(gè)值是保存為sessionid
  • session_data: 這是一個(gè)加密后的信息,用來保存用戶名和密碼等信息
  • expire_data: 過期時(shí)間,Django可以設(shè)置過期時(shí)間

在新的標(biāo)簽頁中打開首頁,依然能看到 username 信息。這證明能自動登錄。


點(diǎn)擊查看大圖

如果用戶退出登錄,再訪問首頁。這時(shí)會發(fā)現(xiàn)看不到了 username 信息了。


點(diǎn)擊查看大圖

5 小結(jié)

實(shí)現(xiàn)自動登錄功能其實(shí)不難,只需要在 Django 的 Sessions 組件。然后根據(jù)場景需要,在 settings.py 配置 session 以及 cookie 等信息。


往前 Django 學(xué)習(xí)筆記文章
Django 學(xué)習(xí)筆記之環(huán)境搭建
Django 學(xué)習(xí)筆記之初始
Django 學(xué)習(xí)筆記之視圖與URL配置
Django 學(xué)習(xí)筆記之模板
Django 學(xué)習(xí)筆記之模型(上)
Django 學(xué)習(xí)筆記之模型(下)
Django 學(xué)習(xí)筆記之后臺管理
Django 學(xué)習(xí)筆記之模型表單
Django 學(xué)習(xí)筆記之使用舊數(shù)據(jù)庫
Django 實(shí)戰(zhàn)1:搭建屬于自己社工查詢系統(tǒng)(上)
Django 實(shí)戰(zhàn)1:搭建屬于自己社工查詢系統(tǒng)(下)
Django 學(xué)習(xí)筆記之模型高級用法(上)
Django 學(xué)習(xí)筆記之模型高級用法(下)
Django 實(shí)現(xiàn)分頁功能
Django 使用會話( sessions )功能


本文原創(chuàng)發(fā)布于微信公眾號「極客猴」,歡迎關(guān)注第一時(shí)間獲取更多原創(chuàng)分享

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 點(diǎn)我查看本文集的說明及目錄。 本項(xiàng)目相關(guān)內(nèi)容包括: 實(shí)現(xiàn)過程: CH7 創(chuàng)建在線商店 CH8 管理支付和訂單 CH...
    學(xué)以致用123閱讀 4,964評論 8 9
  • 此段內(nèi)容簡要來自自強(qiáng)學(xué)堂的教程詳情請查詢自強(qiáng)學(xué)堂 一、 后臺的運(yùn)作流程 接收request請求 處理數(shù)據(jù) 獲取請求...
    coder_ben閱讀 5,337評論 6 56
  • 22年12月更新:個(gè)人網(wǎng)站關(guān)停,如果仍舊對舊教程有興趣參考 Github 的markdown內(nèi)容[https://...
    tangyefei閱讀 35,390評論 22 257
  • 最近,在看一部日劇,叫做《四重奏》,用我的感受來說,這是一部用音樂的外表穿插著愛情去講述的懸疑故事。 四個(gè)年輕的音...
    CBobZ閱讀 1,678評論 3 10
  • 有一種愛叫他給了她一切他能給她的... 有一種拋棄叫她知道他給她的只能如此,還不滿足,所以就拋棄他...
    Gakki喲閱讀 92評論 0 0

友情鏈接更多精彩內(nèi)容