软件测试 | session、cookie和token的区别

103 阅读4分钟

HTTP是一个没有状态的协议,这种特点带来的好处就是执行效率较高,但是缺点也非常明显,这个协议本身是不支持网站关联的,例如

ceshiren.com/ceshiren.com/t/topic/973…这两个网站,必须要使用别的方法将它们两个关联起来。那就是用session、cookie和token。

1)session即会话,是一种持久网络协议,起到了在用户端和服务器创建关联,从而交换数据包的作用。

2)cookie是“小型文本文件”,是某些网站为了辨别用户身份,进行Session跟踪而储存在用户本地终端上的数据(通常经过加密),由用户的客户端计算机暂时或永久保存的信息。

3)token在计算机身份认证中是令牌(临时)的意思,在词法Fenix中是标记的意思。

1.环境搭建演示

为了避免其他因素的干扰,使用Flask编写一个简单的demo server程序,用以演示cookie与session。

demo server的代码如下:

from flask import Flask,session,Request,request,make_response
​
app = Flask(__name__)
request : Request
app.secret_key = "key"@app.route('/')
def hello_world():
    return 'hello,world!'
    
@app.route("/session")
def session_handle():
     #读取请求
     for k, v in request.args.items():
     #收到请求后写入session
       session[k] = v
     #创建服务端响应,将session的内容打印出来
     resp = make_request({k: v for k, v in session.items()})
     for k,v in request.args.item():
     #给服务端设置cookie,并添加cookie字符串进行标识
         resp.set_cookie(f"cookie_{k}",v)
     return resp

2分析session、cookie和token

(1)session和cookie的区别演示

首先使用浏览器的无痕模式对演示网站发起访问,并传入a、b两个参数。以一次请求为例,查看cookie的传递过程。

第一次请求的请求头信息如下(可以看到没有任何的cookie信息):

GET /session?a=1&b=2 HTTP/1.1
Host : 127 0.0.1:5000
Connection:keep-alive
Pragma: no-cache
Cache-Control: no-cashe
sec-ch-ua:"Not A;Brand";v="99","Chromium";v="90","Google Chrom";v="90"
sec-ch-ua-mobile: ?0
Upgrade-Insecure-Requests: 1
User-Agent:Mozilla/5.0(Macintosh;Intel Mac OS X 10_15_0)AppleWebKit/537.36
(KHTML,like Gecko) Chrome/90.0.4430.212 Safari/573.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/
webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding:gzip,deflate,br
Accept-Language: en

第一次请求的响应头信息,向客户端返回了set-cookie字段:

HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 18
Set-cookie:cookie_a=1;Path=/
Set-cookie:cookie_b=2;Path=/
Vary:cookie
Set-cookie: session-eyJhIjoiMSIsImIiOiIYInO.YKSvNA.2sSLXbraXxQ-MfKOLhoLJPZmV9U;
HttpOnly;Path=/
Server:Werkzeug/1.0.1 Python/3.8.7
Date: Web,19 May 2021 06 24:52 GMT

第二次请求的请求头信息,客户端向服务端请发起求时,请求头多出了一个cookie信息,并提交了和第二次set-cookie相同的信息:

GET /session?a=1&b=2 HTTP/1.1
Host: 1270.0.1:5000
省略
cookie: cookie_a=1;cookie_b=2; session=eyJhIjoiMSIsImIiOiIyIn0.YKSvNA.
2sSaLXbraXxQ-MfKOLhoLJPZmV9U

当用户访问带cookie的浏览器时,这个服务端就为这个用户产生了唯一的cookie,并以此作为索引在服务端的后端数据库产生一个项目,接着就给客户的响应报文 中添加一个叫做Set-cookie的首部行,格式为k:v.

该用户下次再访问此网站,在服务端发起请求时添加一个名为cookie首部行,浏览器就可以得知用户的身份,用户就不需要再次输入一些个人信息了。

使用CURL对网站发起了一个GET请求,并传入a、b两个参数

curl 'http://127.0.0.1:5000/session?a=1&b=2' -v -s &>session

查看session文件内的请求及响应内容,如下所示:

* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (1270.0.0.1) port 5000 (#0)
> GET /session?a=1&b=2 HTTP /1.1
> Host:1270.0.1:5000
> User-Agent: curl/7.64.1
> Accept:*/*
>
* HTTP 1.0,assume close after body
< HTTP/1.0 200 OK
< Content-Type:application/json
< Content-Length: 18
< Set-cookie: cookie_a=1; Path=/
< Set-cookie: cookie_b=2; Path=/
< Vary: Cookie
< Set-cookie: session=eyJhIjoiMSIsImIiOiIyIn0.EWX6Qg.M8tEGPyRhlf0iUiLktEqup-4e-U;
HttpOnly; Path=/
< Server: Werkzeug/1.0.1 Python/3.7.5
<
{[18 bytes data]
*Closing connection 0
{"a":"1","b":"2"}}

从上面的内容可以发现,响应值多出了3个Set-cookie字段。其中有一个Set-cookie显示为session=eyJhijoiMSIsIMIiOilyIn0.EWX6Qg.M8tEGPyRhlf0iUiLKtEqup-4e-U;HttpOnly;Path=/,这是Session内容的加密串格式,是通过cookie方式传递的。

(2)token演示

GitHub中有一个使用token的非常经典的场景。访问GitHub页面,依次点击“settings”->"Developer setting"->"Personal access token"项,就会生成一个用于访问GitHub API的token。这个token是没有时效性的,“任何人”都可以使用token来代替HTTPS的Git密码,也可以用API进行身份验证。

使用OAuth令牌对GitHub API进行身份验证(因返回的结果中个人信息太多所以省略展示)。

$ curl -u username:$token https://api.GitHub网站/user

token是无状态的,客户端传递用户数据给服务端,服务端将数据加密就生成了token并传回给客户端。这样客户端每次访问GitHub时都传递token,而服务端解密token之后,即可了解客户的信息。如图6-26所示。

在GitHub中,token只会生成一次,且不会过期,不过在很多其他的Web网站中,token会过期。

image-20230210145834021.png

3.session、cookie和token的联系

session和cookie之间的联系如图6-27(a)所示,token身份验证流程如啼眼6-27(b)所示。

image-20230210145947535.png

(1)session存储在服务端,cookie存储在客户端

(2)cookie可设置为长时间保持;session一般失效时间较短,客户端关闭(默认情况下)或者session超时都会失效。

(3)session记录会话信息;token不会记录会话信息,token是无状态的。

搜索微信公众号:TestingStudio霍格沃兹的干货都很硬核