>[warning] 通過與一些做測試的朋友交流,發現有一些工作了好幾年的朋友,都并不了解Session與Cookie,這里,我用兩個例子來給朋友們好好分析分析!
>
[TOC]
## Session和Cookie相關概念
* Session和Cookie**都是由服務器生成的**。
* Session和Cookie**都是鍵值對**形式保存,主要用于存儲特定的一些狀態值。
* **Session保存在服務器**,**Cookie保存在客戶端**。通常來說,Session的ID會以Cookie的形式返回給客戶端的。
* Session和Cookie都是有**生命周期**的。Cookie的生命周期受到Cookie自身的有效期和客戶端的影響,一般來說,瀏覽器(客戶端)是會自動將存活的Cookie封裝在請求頭里面,向服務器發送。如果Cookie有效期過期或客戶端清理了Cookie,則發送的請求中就沒有Cookie值;Session的生命周期受到Session自身的有效期和客戶端是否關閉的影響。SessionID雖然是已Cookie的形式返回給客戶端,但是它是不受客戶的Cookie容器的管理,而是和客戶端進程有關,即客戶端進程不關閉,一般Session在客戶端就不會失效。
* Session和Cookie都是有**作用域**的。
<br>
>[info]下面我會自己寫一個例子來演示 看不懂相關代碼的,可以留意一下我關于django方面的教程
## 實例演示:以Cookie記錄用戶狀態
**創建一個登陸與歡迎頁面 `login.html`頁面邏輯如下:**
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登錄Session與Cookie</title>
<link rel="stylesheet"
href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
<div class="container">
{% if username %}
<h2>歡迎您 :{{ username }}</h2>
<a href="/logout/">注銷</a>
{% else %}
<form action="/login_cookie/" method="post">
{% csrf_token %}
<div class="form-group">
<label class="sr-only">username</label>
<input type="text" class="form-control" name="username"
placeholder="用戶名"/>
</div>
<div class="form-group">
<label class="sr-only">Password</label>
<input type="password" class="form-control" name="passwd"
placeholder="密碼"/>
</div>
<div class="form-group">
<input class="btn btn-primary" type="submit" value="Submit">
</div>
</form>
{% endif %}
</div>
<script type="application/javascript"
src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script type="application/javascript"
src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</body>
</html>
```
**代碼解釋:**
如果用戶已登錄,則顯示“歡迎您,xx”,并且提供注銷按鈕;
如果用戶未登錄,則顯示一個登錄窗口,讓用戶輸入用戶名與密碼。
**服務端`login/views.py`代碼邏輯如下:**
```python
from django.shortcuts import render
# Create your views here.
def login_cookie(request):
# 從Cookie中獲取用戶名
username = request.COOKIES.get("username", False)
response = render(request, 'login.html', locals())
# 如果POST表單,進行登錄驗證
if request.method == "POST":
username = request.POST['username']
pwd = request.POST['passwd']
if username == 'ptqa' and pwd == '4399':
response = render(request, 'login.html', locals())
# 設置Cookie
response.set_cookie("username", username)
return response
```
**代碼解釋:**
如果是POST方式訪問,從提交過來的數據中驗證用戶是否登錄成功,登錄成功便`將用戶名設置到cookie`,并且返回給客戶端,進入歡迎頁。
如果是GET方式訪問,則`從訪問的cookie中獲取用戶信息`,如果從cookie中能獲取到用戶名,則認為用戶已登錄,返回歡迎頁。
**step1:** 首次訪問http://127.0.0.1:8000/login_cookie/ 可以觀察到 Request headers 中沒有Cookie,頁面處于未登錄狀態

**step2:** 登錄后(輸入賬號名ptqa,密碼4399)自動跳轉首頁,此時可以觀察到,在Response Headers 中存在Set-Cookie:username=ptqa; Path=/

從這里,我們也可以看見,cookie是在服務端設置的。這時候,客戶端接收到服務端設置的cookie后,會保存在瀏覽器的cookie管理器中,下一次再請求時會自動帶上這些cookie,服務端便會知道當前的用戶是已經通過了登錄校驗的用戶。如此這般,便能維持了會話的狀態了。
**step3:** 此時,刷新頁面或新開窗口訪問http://127.0.0.1:8000/login_cookie/ 可觀察到請求中的Request Headers 中自動帶上 Cookie:username=ptqa; 頁面處于已登錄狀態。

**使用JMeter篡改Cookie**
顯然,通過cookie的方式驗證用戶登錄容易被破解,如下使用jmeter篡改Cookie值,則同樣可以進入已登錄狀態顯示界面,如下

發送請求后,可以看到,用戶已經登錄了。

## 實例演示:以Session記錄用戶狀態
**前端登錄與歡迎頁 `login.html `邏輯如下:**
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登錄Session與Cookie</title>
<link rel="stylesheet"
href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
<div class="container">
{% if username %}
<h2>歡迎您 :{{ username }}</h2>
<a href="/logout/">注銷</a>
{% else %}
<form action="/login_session/" method="post">
{% csrf_token %}
<div class="form-group">
<label class="sr-only">username</label>
<input type="text" class="form-control" name="username"
placeholder="用戶名"/>
</div>
<div class="form-group">
<label class="sr-only">Password</label>
<input type="password" class="form-control" name="passwd"
placeholder="密碼"/>
</div>
<div class="form-group">
<input class="btn btn-primary" type="submit" value="Submit">
</div>
</form>
{% endif %}
</div>
<script type="application/javascript"
src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script type="application/javascript"
src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</body>
</html>
```
**代碼解釋:**
如果用戶已登錄,則顯示“歡迎您,xx”,并且提供注銷按鈕;
如果用戶未登錄,則顯示一個登錄窗口,讓用戶輸入用戶名與密碼。
**服務端`login/views.py`的處理邏輯如下:**
```python
from django.shortcuts import render, redirect
# Create your views here.
def login_session(request):
# 從Session中獲取用戶名
username = request.session.get('username', False)
# 如果POST表單,進行登錄驗證
if request.method == "POST":
username = request.POST['username']
pwd = request.POST['passwd']
if username == 'ptqa' and pwd == '4399':
# 設置Session
request.session['username'] = username
# request.session.set_expiry(300) #會讓 Session 在五分鐘后過期
# 登錄不成功或第一訪問就停留在登錄頁面
return render(request, 'login.html', locals())
def logout(request):
if "username" in request.session:
del request.session['username']
return redirect("/login_session/")
```
**代碼解釋:**
如果是POST方式訪問,從提交過來的數據中驗證用戶是否登錄成功,登錄成功便`將用戶名設置到Session中`,并且返回給客戶端,進入歡迎頁。
如果是GET方式訪問,則`從訪問的Session中獲取用戶信息`,如果從Session中能獲取到用戶名,則認為用戶已登錄,返回歡迎頁。
**step1:** 首次訪問http://127.0.0.1:8000/login_session/ 可觀察到Request Headers 中并沒有sessionId 并且處于未登錄狀態

**step2:** 登錄,輸入賬號ptqa,密碼4399 ,在Response Headers 中可以觀察到存在 Set-Cookie:sessionid=qigvbt2ckkcc5rydr46dehzjryg0mh41;

**step3:** 重新刷新頁面或新開窗口,則觀察到在Request Headers 中帶有Cookie Sessionid,并且處于登錄狀態。

**使用JMeter篡改Cookie**
顯然,這種使用sessonid的方式比較安全,如果篡改sessionid,則無法進行登錄。如下:

發送請求后,sessionid在服務端驗證并不存在,所以依然是未登錄的狀態。

<hr style="margin-top:100px">
:-: 
***微信掃一掃,關注“python測試開發圈”,獲取更多測試開發分享!***
- 前言
- Fiddler01-抓包原理介紹與配置
- Fiddler02-菜單功能介紹
- Fiddler03-輕松玩轉Fiddler
- Fiddler04-進階使用FiddlerScript
- Fiddler05-使用FiddlerScript對微信文章互動量進行監控
- Postman01-介紹與安裝
- Postman02-HTTP請求與響應
- Postman03-Collection管理與運行
- Postman04 -變量詳解
- Postman05-初級腳本使用
- Postman06-實例小結篇
- JMeter01-JMeter就是這么簡單
- JMeter02-一個完整實戰包你學會使用JMeter
- JMeter03-在JMeter中使用BeanShell編程
- JMeter04-圖形化和非圖形化運行JMeter
- JMeter05-生成美觀的HTML測試報告
- JMeter06-JMeter+Jenkins實戰
- JMeter07-解析session與cookie