python+pytest介面自動化(9)-cookie繞過登入(保持登入狀態)

語言: CN / TW / HK

在編寫介面自動化測試用例或其他指令碼的過程中,經常會遇到需要繞過使用者名稱/密碼或驗證碼登入,去請求介面的情況,一是因為有時驗證碼會比較複雜,比如有些圖形驗證碼,難以通過介面的方式去處理;再者,每次請求介面前如果都需要先去登入一次,這樣不僅效率低,還耗費資源。

有些網站是使用cookie辨別使用者身份的,此時我們便可以先登入一次,拿到登入成功後的cookie,後續請求時在請求頭中加入該cookie,便可保持登入狀態直接請求。

cookie工作原理

HTTP協議1.0版本是無狀態的,對於事務處理沒有記憶能力,比如使用者登入了某個網站後,再次重新整理這個頁面去請求伺服器,如果沒有相關機制的話,伺服器是不知道這個請求是否還是重新整理之前登入的使用者發出來的。此時,為了維持使用者的登入狀態,即為了使伺服器能夠識別頁面重新整理之後的請求,就可以使用 cookie機制

cookie原理簡單概括如下:

  1. 使用者在客戶端 (一般為瀏覽器) 中訪問某個頁面 ,也就是向伺服器傳送請求。

  2. 伺服器收到請求後,會在響應頭中設定 Set-Cookie 欄位值,該欄位儲存相關資訊和狀態。

  3. 客戶端解析伺服器HTTP響應頭中的Set-Cookie欄位,並以key=value的形式儲存在本地,之後客戶端每次傳送HTTP請求時,都會在請求頭中增加Cookie欄位。

  4. 伺服器接收到客戶端的HTTP請求之後,會從請求頭中取出Cookie資料,來校驗客戶端狀態或身份資訊。

以登入某網站為例,點選登入時請求sign_in介面,請求成功後 (即登入成功後) 在響應頭中會返回set-cookie欄位,如下:

瀏覽器會儲存上圖中set-cookie欄位的值,後續傳送請求 (即登入後進行頁面操作) 時,請求頭中都會攜帶包含剛剛儲存的set-cookie值的cookie,如下所示:

伺服器接收到這個cookie後,便會用它去查詢記憶體中的記錄,有則校驗成功。

由此可知,如果需要繞過使用者名稱密碼、驗證碼等進行模擬登入,然後再去請求其他介面,那麼我們可以先拿到登入成功後的cookie,將cookie放在請求頭中,再去呼叫需要登入才能請求的介面,便能呼叫成功。

cookie繞過登入

1,哪些場景需要使用cookie繞過登入?

  • 網路爬蟲,程式碼去爬取某個網站時需要驗證碼登入,而這時程式碼獲取驗證碼登入有一定難度,就可以先抓取到登入後的cookie用於後續的介面請求。

  • 介面自動化測試,對某個需要登入的專案進行介面測試,每次請求時都先請求登入介面進行登入會影響效率而且極其不方便,這時就可以抓取到第一次登入後的cookie,後續每次介面請求都帶上該cookie,伺服器就會認為是登入狀態。

  • 其他需要繞過登入的場景。

2,接下來舉例說明怎樣編寫python指令碼,利用cookie機制繞過登入。

  • 需求:請求介面獲取部落格園網自己賬號的個人資訊。

  • 需求分析:

    • 需要先登入部落格園,才能去請求獲取個人資訊介面拿到個人資訊
    • 該網站的登入方式有兩種:使用者名稱、密碼登入,手機驗證碼登入
    • 可嘗試使用cookie繞過這兩種登入方式。

3,思路:

  • 首先,先使用手機驗證碼登入網站,Fiddler進行抓包,獲取登入後的cookie資訊;

  • 然後,編寫python程式碼,拿上一步中獲取到的cookie資訊去請求獲取個人資訊介面;

  • 最後,個人資訊獲取成功便說明繞過了登入。

4,實際操作流程如下:

  • 首先,登入網站,Fiddler抓包獲取登入成功後的cookie。

  • 然後,cookie資訊去請求獲取個人資訊介面。

    登入後同樣可以抓取到獲取個人資訊介面的資訊,如下:

    個人資訊介面請求方式為GET,請求URL如圖所示,那麼我們只需要這兩點資訊就足夠了。接下使用上一步中拿到的cookie去請求這個介面。程式碼如下:

    import requests
    
    url = "http://account.cnblogs.com/user/userinfo"
    headers = {
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36 Edg/99.0.1150.30",
        "cookie": "登入成功後的cookie"
    }
    
    res = requests.get(url=url, headers=headers).text
    print(res)

    執行程式碼,結果如下:

    可以看到,成功獲取了個人資訊。

  • 最後,為了驗證是cookie確實繞過了登入,我們修改上面的指令碼,不加入該cookie,請求個人資訊介面,程式碼如下:

    import requests
    
    url = "http://account.cnblogs.com/user/userinfo"
    headers = {
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36 Edg/99.0.1150.30"
    }
    
    res = requests.get(url=url, headers=headers).text
    print(res)

    執行後結果如下:

    從上圖可以看出來,不加登入成功後的cookie去請求介面,則會提示先登入或註冊。

總結

cookie繞過登入其實是登入狀態保持,而不是真的不需要登入。

並非所有的網站都是使用cookie機制,除了cookie機制外,還有session、token等方式進行會話保持,這在後續的文章中會進行說明。