>[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,页面处于未登录状态
![](https://box.kancloud.cn/0fac9b117b8fb30f00a3273c5f075e68_979x547.jpg)
**step2:** 登录后(输入账号名ptqa,密码4399)自动跳转首页,此时可以观察到,在Response Headers 中存在Set-Cookie:username=ptqa; Path=/
![](https://box.kancloud.cn/25cc6c0fd695c27ed3cfc7095e012b17_991x606.jpg)
从这里,我们也可以看见,cookie是在服务端设置的。这时候,客户端接收到服务端设置的cookie后,会保存在浏览器的cookie管理器中,下一次再请求时会自动带上这些cookie,服务端便会知道当前的用户是已经通过了登录校验的用户。如此这般,便能维持了会话的状态了。
**step3:** 此时,刷新页面或新开窗口访问http://127.0.0.1:8000/login_cookie/ 可观察到请求中的Request Headers 中自动带上 Cookie:username=ptqa; 页面处于已登录状态。
![](https://box.kancloud.cn/58bee489e9e1187cdb2bdce139382ffa_979x554.jpg)
**使用JMeter篡改Cookie**
显然,通过cookie的方式验证用户登录容易被破解,如下使用jmeter篡改Cookie值,则同样可以进入已登录状态显示界面,如下
![](https://box.kancloud.cn/3a075f61a4acd614f93ca6ba8cecbdb7_987x213.jpg)
发送请求后,可以看到,用户已经登录了。
![](https://box.kancloud.cn/478c0d46e4e59391e7087d9e3605e621_984x466.jpg)
## 实例演示:以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 并且处于未登录状态
![](https://box.kancloud.cn/badd15de3df051830c2612140c9c2766_963x512.jpg)
**step2:** 登录,输入账号ptqa,密码4399 ,在Response Headers 中可以观察到存在 Set-Cookie:sessionid=qigvbt2ckkcc5rydr46dehzjryg0mh41;
![](https://box.kancloud.cn/ebdae352b3ac5dbf5efdf5cd9de2cd6f_964x529.jpg)
**step3:** 重新刷新页面或新开窗口,则观察到在Request Headers 中带有Cookie Sessionid,并且处于登录状态。
![](https://box.kancloud.cn/edacb879f6ad69ab0f1a54b3ba38d77c_996x467.jpg)
**使用JMeter篡改Cookie**
显然,这种使用sessonid的方式比较安全,如果篡改sessionid,则无法进行登录。如下:
![](https://box.kancloud.cn/62b2715c63bde66e2717d9e3036c944d_977x167.jpg)
发送请求后,sessionid在服务端验证并不存在,所以依然是未登录的状态。
![](https://box.kancloud.cn/83101e3a1bfd4be4d2d2c0dab8ed8972_988x393.jpg)
<hr style="margin-top:100px">
:-: ![](https://box.kancloud.cn/331f659e8e6cddb0d9f182e00e32803f_258x258.jpg)
***微信扫一扫,关注“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