WEB接口開發與自動化測試-讀書筆記4 寫個登錄功能

請繼續在筆記3的基礎上開發。

導讀:

本章內容學習:

  1. 登錄表單(form)中的數據以GET/POST提交到服務器;
  2. Django驗證用戶名/密碼的正確性;
  3. 驗證成功後如何處理;
  4. 驗證失敗將錯誤提示返回客戶端。

一、先寫個登錄界面

打開…/sign/templates/index.html文件

index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Django Demo</title>
</head>
<body>
<h1>發佈會管理</h1>
<form>
	<input name="username" type="text" placeholder="username" ><br>
	<input name="password" type="password" placeholder="password" ><br>
    <button id="btn" type="submit">登錄</button>
</form>
</body>
</html>

啓動D服務,訪問:http://127.0.0.1:8000/index/
在這裏插入圖片描述
上圖我們看到登錄界面已經寫好了,但它還不可用。
接下來我通GET與POST請求來實現登錄功能。

二、GET與POST請求

2.1GET請求

(get傳參方式:form method=“get”)
打開…/sign/templates/index.html文件

index.html
......
<form method="get">
    <input name="username" type="text" placeholder="username" ><br>
    <input name="password" type="password" placeholder="password" ><br>
    <button id="btn" type="submit">登錄</button>
</form>
......

刷新登錄頁面,輸入用戶名/密碼(admin/admin123),單擊“登錄”按鈕
在這裏插入圖片描述
查看瀏覽器URL地址欄:
http://127.0.0.1:8000/index/?username=admin&password=admin123

GET方法會將用戶提交的數據添加到URL地址中,路徑後面跟問號“?”。username爲HTML代碼中<input>標籤的name屬性值(name=“username”),admin是我們在用戶名輸入框中填寫的用戶名。password=admin123的取值方式與用戶名相同。多個參數之間“&”符號隔開。

2.2POST請求

同樣是上面的代碼,將form表單中的屬性修改爲method=“post”,刷新頁面,輸入用戶名/密碼(admin/admin123),單擊“登錄”按鈕。彈出“CSRF verification failed. Request aborted.”

......
<form method="post">
    <input name="username" type="text" placeholder="username" ><br>
    <input name="password" type="password" placeholder="password" ><br>
    <button id="btn" type="submit">登錄</button>
</form>
......

在這裏插入圖片描述
看到這個報錯,不要着急,靜下心來仔細閱讀上面的幫助信息。
這個錯誤是說我們在使用Django的模板未正確使用CSRF(Cross-Site Request Forgery “跨站請求僞造”)令牌!Django針對CSRF的保護措施是在生成的每個表單中放置一個自動生成的令牌,通過這個令牌判斷POST請求是否來自同一個網站。
之前的模板都是純粹的HTML,這裏首次用到Django的模板,使用“模板標籤”(TemplateTag)添加CSRF令牌。在from表單中添加{% csrf_token %}。

<form method="post">
    <input name="username" type="text" placeholder="username" ><br>
    <input name="password" type="password" placeholder="password" ><br>
    <button id="btn" type="submit">登錄</button>
    {% csrf_token %}
</form>

然後,刷新頁面,輸入用戶名/密碼(admin/admin123),單擊“登錄”按鈕。按F12調試工具查看POST請求,我們會看到除了“usrnname"和”password“參數外,還多了一個”csrfmiddlewaretoken“的參數。當頁面向Django服務器發送一個POST請求時,服務器端要求客端加上”csrfmiddlewaretoken“字段,該字段的值爲當前會話ID加上一個密鑰的散列值。
在這裏插入圖片描述
如果想忽略掉該檢查,那麼可以在…/guest/settings.py文件中註釋掉csrf。

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
   # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

三、處理登錄請求

那麼Django是如何接收請求的數據並加以處理的呢?可以通過form表單的action屬性來指定提交的路徑。
打開index.html文件,添加內容如下:

......
<form method="post" action="/login_action/">
......

當我們填寫用戶名/密碼,單擊”登錄“按鈕時,由http://127.0.0.1:8000/login_action/路徑來提交登錄請求。所以,打開…/guest/urls.py文件添加login_action的路由。

from sign import views           #導入sign應用views文件

urlpatterns = [
   ......
    url(r'login_action/$',views.login_action),
]

登錄請求由views.py視圖文件的login_action函數來處理,打開sign/views.py文件,創建login_action視圖函數。

......
# 登錄動作
def login_action(request):
    if request.method == 'POST':
        username = request.POST.get('username', '')
        password = request.POST.get('password', '')
        if username == 'admin' and password == 'admin123':
            return HttpResponse('登錄成功!')
        else:
            return render(request,'index.html',{'error':'用戶名密碼錯誤!'})

分析:
1、首先,通過request.method得到客戶端的請求方式,並判斷其是否爲POST方式的請求。
2、接着,通過request.POST來獲取POST請求。通過.get()方法獲取“username”和“password”所獲取的用戶名/密碼(admin/admin123)。如果參數爲空,則返回一個空的字符串。
3、最後,通過if語句判斷username和passwoed的值是否爲“admin/admin123”。如果是則通過HttpResponse類返回字符串“登錄成功”。否則,將通過render返回index.html登錄頁面,並且順帶返回錯誤提示的字典{‘error’:‘用戶名和密碼錯誤!’}。

但是,登錄頁面並沒有顯示錯誤提示的位置,打開index.html頁面修改如下:

<form method="post" action="/login_action/">
    <input name="username" type="text" placeholder="username" ><br>
    <input name="password" type="password" placeholder="password" ><br>
    {{ error }}<br>
    <button id="btn" type="submit">登錄</button>
    {% csrf_token %}
</form>

使用Django的模板語言,添加{{ error }}
,它對應render返回字典中的key,即‘error’在登錄失敗的頁面中顯示對應的value,即’用戶名密碼錯誤!‘。
好了,現在來體驗下登錄功能。
在這裏插入圖片描述
在這裏插入圖片描述

四、登錄成功頁

登錄成功返回”登錄成功!”字符串只是一種臨時方案,只是爲了方便驗證登錄的處理邏輯,現在驗證沒有問題之後,需要通過HTML頁面來替換。

首先,創建…/templates/event_manage.html頁面。(發佈會管理頁面)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>發佈會管理系統</title>
</head>
<body>
<h1>登錄成功!</h1>
</body>
</html>

打開…/sign/views.py文件,修改內容:

from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect

......
# 登錄動作
def login_action(request):
    if request.method == 'POST':
        username = request.POST.get('username', '')
        password = request.POST.get('password', '')
        if username == 'admin' and password == 'admin123':
            return HttpResponseRedirect('/event_manage/')
        else:
            return render(request,'index.html',{'error':'用戶名密碼錯誤!'})
        
# 發佈會管理
def event_manage(request):
    return render(request,"event_manage.html")

此處用到一個新類HttpResponseRedirect,它可以對路徑進行重定向,從而將登錄成功之後的請求指向/event_manage/目錄,即:http://127.0.0.1:8000/event_manage/
創建event_manage函數,用於返回發佈會管理頁面event_manage.html。

最後,我們要記的在…/guest.urls.py 文件中添加event_manage/的路由。

from sign import views           #導入sign應用views文件

urlpatterns = [
......
    url(r'event_manage/$',views.event_manage),
]

再來登錄一下,試試修改後的功能吧!
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章