1. 程式人生 > >python測試開發django-43.session機制(登錄/註銷)

python測試開發django-43.session機制(登錄/註銷)

img import eth username 新頁面 分享 gis code 更多

前言

當我們登錄訪問一個網站時,服務器需要識別到你已經登錄了,才有相應的權限訪問登錄之後的頁面。用戶退出登錄後,將無權限訪問再訪問登錄後的頁面。
從登錄到退出的一整個流程,可以看成是與服務器的一次會話,也就是session。django裏面可以引入session機制實現登錄狀態的校驗。

session設置

Django默認支持Session,其內部提供了5種類型的Session供開發者使用:數據庫(默認)、緩存、文件、緩存+數據庫、加密cookie。
默認是將Session數據存儲在數據庫中,在django_session 表中可以查看到。使用最新的 Django 2.X 版本創建新項目的時,在settings.py 中會默認啟用session功能。

INSTALLED_APPS = [
    'django.contrib.sessions',     # 默認啟用sessions應用
]

MIDDLEWARE = [
    'django.contrib.sessions.middleware.SessionMiddleware',    # 默認啟用 Session 中間層
]

執行makemigrations和migrate同步數據庫後,可以看到用一張django_session表存放session相關的信息

技術分享圖片

這張表裏面用三個字段:session_key(鍵), session_data(值),expire_date(過期時間)

常用操作

通過HttpRequest對象(也就是視圖函數裏面的request參數)的session屬性進行會話的新增key,查詢,和清除session

新增session鍵值對

request.session["key"]="value"

根據key值讀取value,如果沒讀取到,就讀默認值

request.session.get(‘key‘, "默認值")

也可以通過這種方式讀取

request.session["key"]

刪除session

request.session.clear()

刪除session中的指定鍵及值,在存儲中只刪除某個鍵及對應的值

del request.session[‘key‘]

清除session數據,在存儲中刪除session的整條數據。

request.session.flush()

會話超時設置,如果不設置,django默認是2個星期過期

request.session.set_expiry(value)

  • 如果value是一個整數,會話將在value秒沒有活動後過期。
  • 如果value為0,那麽用戶會話的Cookie將在用戶的瀏覽器關閉時過期。
  • 如果value為None,那麽會話永不過期。

登錄實例

登錄頁/templates/login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登錄</title>
</head>
<body>
     <div style="margin: 15% 40%;">
        <h1>歡迎登錄!</h1>
       <form action="/login_test/" method="post">
           {% csrf_token %}
            <p>
                <label for="id_username">用戶名:</label>
                <input type="text" id="id_username" name="username" placeholder="用戶名" autofocus required />
            </p>
            <p>
                <label for="id_password">密碼:</label>
                <input type="password" id="id_password" placeholder="密碼" name="password" required >
            </p>
            <p style="color:red">
                {{msg}}
            </p>
            <input type="submit" value="確定">
            <a href="/forget">忘記密碼?</a>
       </form>
         <br><br>
         <a href="/register">新用戶先註冊</a>
    </div>

</body>
</html>

登錄成功頁/templates/success.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>修改密碼</title>
</head>
<body>
     <div style="margin: 15% 40%;">
        <h1>登錄成功!</h1><br><br>
         <h2>
             <a href="/xadmin/">進主頁更多功能</a>
         </h2>

         <a href="/logout/">
             <i class="show-sm fa fa-sign-out"></i>
             <span class="hide-sm">註銷</span>
         </a>

         <form action="/success/" method="post">
           {% csrf_token %}
            <p>
                <label for="id_psw">原始密碼:</label>
                <input type="text" id="id_psw" name="psw" placeholder="原密碼" autofocus required />
            </p>
            <p>
                <label for="id_new">新密碼:</label>
                <input type="password" id="id_new" placeholder="新密碼" name="psw_new" required >
            </p>
             <p>
                <label for="id_re">確認新密碼:</label>
                <input type="password" id="id_re" placeholder="重復新密碼" name="psw_re" required >
            </p>
            <input type="submit" value="確定">
             <p style="color:red">
                {{msg}}
            </p>
            <a href="/login_test">登錄</a>
         </form>
         <br><br>
    </div>
</body>
</html>

視圖函數views.py

from django.shortcuts import render
from django.http import HttpResponse, JsonResponse, HttpResponseRedirect
from django.contrib.auth import login,  logout, authenticate
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required

def loginView(request):
    '''登錄'''
    if request.method == "POST":
        username = request.POST.get('username', '')
        psw = request.POST.get('password', '')
        user = authenticate(username=username, password=psw)
        if user is not None:
            if user.is_active:
                login(request, user=user)
                request.session['user'] = username
                return HttpResponseRedirect('/success')
        else:
            return render(request, 'login.html', {'msg': '賬號或密碼錯誤!'})
    else:
        return render(request, 'login.html', {'msg': ''})

@login_required
def successView(request):
    '''登錄成功頁'''
    return render(request, 'success.html', {'msg': ''})


def logoutView(request):
    '''退出登陸'''
    logout(request)   # 這個方法,會將存儲在用戶session的數據全部清空
    return render(request, 'login.html', {'msg': ''})

urls.py配置訪問地址

from django.conf.urls import url
from hello import views
urlpatterns = [
    url(r'^login/', views.loginView),     # 登錄
    url(r'^logout/', views.logoutView),   # 退出
    url(r'^success/', views.successView),

查看登錄session

當第一次訪問(使用瀏覽器的無痕模式)登錄頁http://localhost:8000/login/,服務端會返回一個cookies值:csrftoken

技術分享圖片

當輸入賬號和密碼登錄成功後,會用個sessionid存到cookies裏面

技術分享圖片

點登陸成功頁面的“註銷”按鈕,sessionid會被清空

技術分享圖片

重新刷新頁面,sessionid就沒有了

python測試開發django-43.session機制(登錄/註銷)