接口測試經(jīng)典面試題:Session苍柏、cookie尼斧、token有什么區(qū)別?

接口測試經(jīng)典面試題:Session试吁、cookie棺棵、token有什么區(qū)別?

本文節(jié)選自霍格沃茲測試開發(fā)學社內(nèi)部教材

HTTP是一個沒有狀態(tài)的協(xié)議熄捍,這種特點帶來的好處就是效率較高烛恤,但是缺點也非常明顯,這個協(xié)議本身是不支持網(wǎng)站的關聯(lián)的余耽,比如https://ceshiren.com/https://ceshiren.com/t/topic/9737/7這兩個網(wǎng)站缚柏,必須要使用別的方法將它們兩個關聯(lián)起來。那就是session 碟贾、cookie 船惨、token。

  • session 即會話缕陕,是一種持久網(wǎng)絡協(xié)議粱锐,起到了在用戶端和服務器端創(chuàng)建關聯(lián),從而交換數(shù)據(jù)包的作用扛邑。

  • cookie 是“小型文本文件”怜浅,是某些網(wǎng)站為了辨別用戶身份,進行 session 跟蹤而儲存在用戶本地終端上的數(shù)據(jù)(通常經(jīng)過加密)蔬崩,由用戶客戶端計算機暫時或永久保存的信息恶座。

  • token 在計算機身份認證中是令牌(臨時)的意思,在詞法分析中是標記的意思沥阳。一般作為邀請跨琳、登錄系統(tǒng)使用。

與 get桐罕、post 區(qū)別實戰(zhàn)詳解 章節(jié)相同脉让,為了避免其他因素的干擾,使用 Flask 編寫一個簡單的 demo server(Flask 的安裝與啟動參考 get功炮、post 區(qū)別實戰(zhàn)詳解 章節(jié))溅潜,來演示 cookie 與 session。

demo server 演示代碼

from flask import Flask,session,Request, request,make_responseapp = Flask(__name__)request: Requestapp.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
    #創(chuàng)建服務器響應薪伏,將session的內(nèi)容打印出來
    resp = make_response({k: v for k, v in session.items()})
    for k, v in request.args.items():
    #給服務器設置cookie滚澜,并添加cookie字符串進行標識
        resp.set_cookie(f"cookie_{k}", v)
    return resp

首先使用瀏覽器的無痕模式對演示網(wǎng)站發(fā)起訪問,并傳入 a嫁怀、b 兩個參數(shù) 以一次請求為例设捐,查看 cookie 的傳遞過程

第一次請求的請求頭信息如下借浊,可以看到?jīng)]有任何的 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-cache
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="90", "Google Chrome";v="90"sec-ch-ua-mobile: ?0
Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.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: 18Set-Cookie: cookie_a=1; Path=/
Set-Cookie: cookie_b=2; Path=/
Vary: Cookie
Set-Cookie: session=eyJhIjoiMSIsImIiOiIyIn0.YKSvNA.2sSLXbraXxQ-MfKOLhoLJPZmV9U; HttpOnly; Path=/
Server: Werkzeug/1.0.1 Python/3.8.7
Date: Wed, 19 May 2021 06:24:52 GMT

第二次請求的請求頭信息萝招,客戶端向服務端請求時請求頭多出了一個 cookie 信息蚂斤,并提交了和第二次 set-cookie 相同的信息:

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

當用戶訪問帶 cookie 瀏覽器時,這個服務器就為這個用戶產(chǎn)生了唯一的 cookie即寒,并以此作為索引在服務器的后端數(shù)據(jù)庫產(chǎn)生一個項目橡淆,接著就給客戶端的響應報文中添加一個叫做 Set-cookie 的首部行召噩,格式為 k:v母赵。

這樣當該用戶下次再訪問此網(wǎng)站時,就會在對服務器發(fā)起請求的時候添加一個名 Cookie 的首部行具滴。瀏覽器由此就可以得知用戶的身份凹嘲,從而用戶就不需要再次重新輸入一些個人信息。

使用 curl 命令對網(wǎng)站發(fā)起了一個 get 請求构韵,并傳入 a周蹭、b 兩個參數(shù)

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

查看 session 文件內(nèi)的請求以及響應內(nèi)容

*   Trying 127.0.0.1...
* TCP_NODELAY set* Connected to 127.0.0.1 (127.0.0.1) port 5000 (#0)> GET /session?a=1&b=2 HTTP/1.1
> Host: 127.0.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"}

從上面可以發(fā)現(xiàn),與上一章節(jié)內(nèi)容不同的是響應值多出了 3 個Set-Cookie字段疲恢。下面有一個Set-Cookie顯示為session=eyJhIjoiMSIsImIiOiIyIn0.EWX6Qg.M8tEGPyRhlf0iUiLktEqup-4e-U; HttpOnly; Path=/凶朗,由此可見 session 一般是加密串格式,可以通過 cookie 傳遞显拳。

token 的使用有一個非常經(jīng)典的場景棚愤,就是在 github 中的使用。在 github->settings->Developer settings->Personal access tokens 中杂数,可以生成一個 token 用于訪問 github 的 api宛畦,這個 token 是沒有時效性的,“任何人”可以使用它們代替通過 HTTPS 的 Git 密碼揍移,也可以用來通過基本身份驗證向 API 進行身份驗證次和。

[圖片上傳失敗...(image-f66c0-1658365341157)]

使用 OAuth 令牌對 GitHub API 進行身份驗證(因返回結果個人信息太多所以省略展示)

$ curl -u username:$token https://api.github.com/user

token是無狀態(tài)的,客戶端傳遞用戶數(shù)據(jù)給服務端后那伐,服務端將數(shù)據(jù)加密就生成了token并傳回給客戶端踏施。這樣客戶端每次訪問時都傳遞token,而服務端解密token之后罕邀,即可了解客戶的信息读规。

在 github 中,token 只會生成一次燃少,且不會過期束亏,不過在很多其他的 web 應用網(wǎng)站,token 會存在過期機制阵具。

@startuml
autonumber
title session碍遍、cookie過程
participant 客戶端 as c
participant 服務器 as s

c -> s: 第一次請求
s -> s: 創(chuàng)建SessionID并保存
s -> c: 返回SessionID定铜,并Set-Cookie
c -> c: Cookie保存\n在瀏覽器
c -> s: 第二次請求,請求中攜帶Cookie和SessionId
s -> s: 判斷SessionId\n屬于哪個用戶
s -> c: 響應 

@enduml
@startuml
autonumber
title token身份驗證流程

participant 客戶端 as c
participant 服務器 as s

c -> s: 第一次請求怕敬,攜帶用戶信息(賬戶揣炕、密碼)
s -> s: 用戶信息加密\n之后得到token
s -> c: 返回token
c -> s: 請求時攜帶token
s -> s: 對token解密之后做認證
s -> c: 響應 

@enduml
  • session 存儲在服務器端,cookie 存儲在客戶端东跪。

  • cookie 可設置為長時間保持畸陡,session 一般失效時間較短,客戶端關閉(默認情況下)或者 session 超時都會失效虽填。

  • session記錄會話信息丁恭,token不會記錄會話信息。token是無狀態(tài)的牲览。

更多技術文章

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市第献,隨后出現(xiàn)的幾起案子兔港,更是在濱河造成了極大的恐慌庸毫,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件衫樊,死亡現(xiàn)場離奇詭異,居然都是意外死亡橡伞,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進店門兑徘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來刚盈,“玉大人,你說我怎么就攤上這事挂脑∨菏” “怎么了崭闲?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長橄仍。 經(jīng)常有香客問我,道長侮繁,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任宪哩,我火速辦了婚禮,結果婚禮上彬祖,老公的妹妹穿的比我還像新娘品抽。我一直安慰自己,他們只是感情好桑包,可當我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布纺非。 她就那樣靜靜地躺著,像睡著了一般弱左。 火紅的嫁衣襯著肌膚如雪炕淮。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天涂圆,我揣著相機與錄音,去河邊找鬼模狭。 笑死,一個胖子當著我的面吹牛嚼鹉,可吹牛的內(nèi)容都是我干的驱富。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼线脚,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了浑侥?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蠢莺,失蹤者是張志新(化名)和其女友劉穎零如,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體考蕾,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年蚯窥,在試婚紗的時候發(fā)現(xiàn)自己被綠了塞帐。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡荷鼠,死狀恐怖榔幸,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情削咆,我是刑警寧澤,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布鳞陨,位于F島的核電站奏黑,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏熟史。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一碘菜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧忍啸,春花似錦、人聲如沸计雌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽翁脆。三九已至,卻和暖如春反番,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背罢缸。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工祖能, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蛾洛,地道東北人养铸。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓钞螟,卻偏偏與公主長得像,于是被迫代替她去往敵國和親鳞滨。 傳聞我的和親對象是個殘疾皇子蟆淀,可洞房花燭夜當晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容