使用jMeter构造逻辑上有依赖关系的一系列并发请求
相信前端開發(fā)工程師對CSRF(Cross-site request forgery)跨站請求偽造這個(gè)概念都非常熟悉,有的時(shí)候也簡寫成XSRF,是一種對網(wǎng)站的惡意利用。
盡管聽起來像跨站腳本(XSS),但它與XSS非常不同,XSS利用站點(diǎn)內(nèi)的信任用戶,而CSRF則通過偽裝成受信任用戶的請求來利用受信任的網(wǎng)站。
CSRF攻擊的防御方式有多種,最簡單最易實(shí)現(xiàn)的一種思路就是在客戶端向服務(wù)器發(fā)起的請求中放入攻擊者無法偽造的信息,并且該信息沒有存儲于 cookie 之中。技術(shù)上來說,當(dāng)客戶端向服務(wù)器發(fā)起請求執(zhí)行一些敏感操作之前(比如用HTTP post實(shí)現(xiàn)的轉(zhuǎn)賬,扣款等功能),服務(wù)器端隨機(jī)產(chǎn)生一個(gè)token,返回給客戶端。客戶端接下來的操作,必須在HTTP請求中以參數(shù)的形式把這個(gè)服務(wù)器端頒發(fā)的token帶上。同時(shí)服務(wù)器端在實(shí)現(xiàn)給客戶端分配token的同時(shí),也要加入一個(gè)token校驗(yàn)機(jī)制。如果請求中沒有 token 或者 token 內(nèi)容不正確,則認(rèn)為可能是 CSRF 攻擊而拒絕該請求。這個(gè)token我們一般稱為CSRF token。
講了這么多,是為了引入本文想要討論的話題。假設(shè)我想用jMeter測試一個(gè)OOdata服務(wù)創(chuàng)建Service Ticket的性能。因?yàn)閯?chuàng)建功能不像讀操作,執(zhí)行之后會對系統(tǒng)產(chǎn)生持久化影響(Persistence side-effect), 因此服務(wù)器端的實(shí)現(xiàn)加入了CSRF token的校驗(yàn)。這就是說,如果我們直接用jMeter構(gòu)造并發(fā)的HTTP post請求,是沒有辦法完成測試的,這些請求因?yàn)闆]有包含CSRF token,會被服務(wù)器端直接拒絕掉。
根據(jù)前面描述的CSRF攻防原理,CSRF token是服務(wù)器端隨機(jī)生成的,客戶端無法用任何技術(shù)進(jìn)行偽造,因?yàn)闉榱藴y試接口HTTP post操作進(jìn)行Service Ticket的創(chuàng)建,我們必須構(gòu)造一個(gè)它的前置HTTP GET請求,專門用于得到服務(wù)器返回的CSRF token,然后再構(gòu)造真正用于性能測試的HTTP POST請求,把第一步GET請求獲得的CSRF token附到POST請求的頭部中去。
本文介紹在jMeter里如何維護(hù)并配置這種具有依賴關(guān)系的一組請求。
當(dāng)然如果您不喜歡用jMeter,想自己寫代碼實(shí)現(xiàn),也是可以的。可以參考我放在github上的Java代碼實(shí)現(xiàn)。
用jMeter的好處是不需要編程,通過簡單的配置就能實(shí)現(xiàn)這個(gè)性能測試需求,一般沒有開發(fā)背景的測試人員也能獨(dú)立完成。
First let us have a look how JMeter could archive the same without even one line of programming.
My project in JMeter is displayed with the following hierarchy. I have configured with “Number of 5 threads” in my thread group, so once executed, the response time of these 5 threads are displayed in result table together with average response time.
從下圖能看出,因?yàn)槟肅SRF token的HTTP GET在邏輯上必須先于實(shí)際需要測試性能的HTTP POST請求,這實(shí)際上構(gòu)成了一個(gè)Transaction-事務(wù),所以我使用jMeter里提供的Transaction Controller來管理。
Some key points for this JMeter project creation
(1) Since now one thread should cover both XSRF token fetch via HTTP get and Service request creation via HTTP post, so a transaction controller is necessary to include both request.
(2) Create the first HTTP request to fetch XSRF token. The setting could be found below: adding a http header field with name as
x-csrf-token and value as “fetch”:
在HTTP GET請求的頭部加上一個(gè)名為x-csrf-token的字段,值賦成fetch。這樣服務(wù)器接到這個(gè)請求,就知道這是客戶端發(fā)起的CSRF token請求,于是服務(wù)器響應(yīng)這個(gè)請求,把創(chuàng)建好的隨機(jī)CSRF token通過HTTP response頭部字段的方式返回給客戶端。
下一個(gè)問題就是,服務(wù)器返回給客戶端合法的CSRF token后,jMeter如何讀取到這個(gè)token,并用于接下來的請求?
幸運(yùn)的是,jMeter提供了正則表達(dá)式提取式,可以讓我們很方便地從HTTP響應(yīng)結(jié)構(gòu)中提取出token來。
Create a Regular Expression Extractor to parse the XSRF token from response header and stored it to a variable named “jerrycsrftoken”.
下圖構(gòu)造了一個(gè)jMeter正則表達(dá)式提取器,工作于HTTP響應(yīng)的頭部字段,解析出的token值存儲于變量jerrycsrftoken中。
Before you continue, please make sure that the XSRF token is correctly parsed from request header, which could be confirmed by printing it out in a debug sample:
這個(gè)請求構(gòu)造完之后,我們先試著運(yùn)行一次,確保在變量jerrycsrftoken里確實(shí)看到解析好的CSRF token。
(3) Create another HTTP request with type POST.
這時(shí)萬事俱備,我們可以開始構(gòu)造真正要進(jìn)行性能測試的HTTP post,即Service Ticket的創(chuàng)建請求了。
請求的報(bào)文正文:
Just paste the following text to the tab “Body Data”:
In the body text I use a user-defined variable ${uuid} which we could create it in last step. And for this post request, use the XSRF token fetched from previous HTTP get request.
前面說過,POST請求的頭部需要加上合法的CSRF token,此處我們使用前面GET請求已經(jīng)拿到的并且存儲于變量jerrycsrftoken中的token值:
我希望最后通過并發(fā)測試生成的Service Ticket的描述信息的后綴是1到100的隨機(jī)正整數(shù),因此我使用jMeter里自帶的一個(gè)隨機(jī)數(shù)發(fā)生器:
(4) As the last step, create a user variable by using JMeter built-in function __Random, to create a random number between 1 ~ 100 as a fragment of created Service Request description.
Now execute the Thread group, and the execution detail for these three HTTP request could be reviewed separately in tree view:
試著運(yùn)行一下,發(fā)現(xiàn)這個(gè)POST操作確實(shí)按照我們期望的那樣,在HTTP頭部字段里加上了正確合法的CSRF token:
For example, the XSRF token is successfully fetched in the first request: rdPy7zNj_uKDYvQLgfQCFA==
And used as one header field in second HTTP Post request as expected:
And finally in UI we could find the created Service request with random number between 1 ~ 100 as postfix:
在UI上觀測到我構(gòu)造的5個(gè)并發(fā)請求創(chuàng)建的Service Ticket,說明CSRF token在服務(wù)器端的校驗(yàn)成功,同時(shí)發(fā)現(xiàn)描述信息都帶上了隨機(jī)數(shù),說明我的jMeter隨機(jī)數(shù)生成器的用法也正確。
希望本文對大家的工作有所幫助。
要獲取更多Jerry的原創(chuàng)文章,請關(guān)注公眾號"汪子熙":
總結(jié)
以上是生活随笔為你收集整理的使用jMeter构造逻辑上有依赖关系的一系列并发请求的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: lol霸天剑魔炫彩怎么买(艾欧尼亚VS诺
- 下一篇: SAP CRM里是如何检测一个BP是否存