最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用Python優(yōu)雅地處理帶有JWT認(rèn)證的接口提交

 更新時(shí)間:2026年01月20日 08:34:32   作者:小莊-Python辦公  
在傳統(tǒng)的網(wǎng)頁爬蟲開發(fā)中,我們習(xí)慣于直接請(qǐng)求目標(biāo) URL,解析 HTML,提取數(shù)據(jù),然而,隨著現(xiàn)代 Web 應(yīng)用架構(gòu)的演進(jìn),前后端分離(SPA)已成為主流,為了保護(hù)這些接口的安全,開發(fā)者往往會(huì)設(shè)置一道門衛(wèi)JWT,所以本文給大家介紹了如何使用Python優(yōu)雅地處理帶有JWT認(rèn)證的接口提交

第一章:當(dāng)爬蟲遇上“隱形門衛(wèi)”——JWT 認(rèn)證機(jī)制解析

在傳統(tǒng)的網(wǎng)頁爬蟲開發(fā)中,我們習(xí)慣于直接請(qǐng)求目標(biāo) URL,解析 HTML,提取數(shù)據(jù)。然而,隨著現(xiàn)代 Web 應(yīng)用架構(gòu)的演進(jìn),前后端分離(SPA)已成為主流。這意味著數(shù)據(jù)不再是直接嵌入在 HTML 中,而是通過 API 接口以 JSON 格式交互。為了保護(hù)這些接口的安全,開發(fā)者往往會(huì)設(shè)置一道“門衛(wèi)”——JWT (JSON Web Token)。

對(duì)于爬蟲工程師而言,理解 JWT 的工作原理是繞過這道門衛(wèi)的關(guān)鍵。

1.1 什么是 JWT?

JWT 是一種開放標(biāo)準(zhǔn)(RFC 7519),用于在網(wǎng)絡(luò)應(yīng)用環(huán)境間傳遞聲明。它將用戶信息加密成一個(gè) Token,通常由三部分組成:

  1. Header(頭部):包含令牌類型和簽名算法(如 HMAC SHA256 或 RSA)。
  2. Payload(負(fù)載):包含用戶身份信息(如用戶ID、過期時(shí)間)。
  3. Signature(簽名):這是安全性的核心。服務(wù)器使用 Header 和 Payload,配合只有服務(wù)器知道的密鑰(Secret)進(jìn)行簽名。

1.2 為什么爬蟲需要特別關(guān)注 JWT?

在傳統(tǒng)的 Session/Cookie 機(jī)制中,服務(wù)器會(huì)在客戶端保留一個(gè) Session ID,爬蟲只需保持 Cookie 即可。但在 JWT 模式下,服務(wù)器是無狀態(tài)的??蛻舳耍g覽器)在登錄成功后,會(huì)收到一個(gè)長字符串(Token),之后的每一次請(qǐng)求,都必須在 HTTP Header 中攜帶這個(gè) Token(通常是 Authorization: Bearer <token>)。

如果我們的爬蟲忽略了這個(gè)機(jī)制,直接去請(qǐng)求需要登錄的接口,服務(wù)器會(huì)直接返回 401 Unauthorized,就像被門衛(wèi)直接攔在門外一樣。

1.3 JWT 的“雙刃劍”對(duì)爬蟲的影響

  • 優(yōu)勢:Token 可以跨域使用,且不需要服務(wù)器查詢數(shù)據(jù)庫驗(yàn)證 Session,速度極快。
  • 挑戰(zhàn):Token 有過期時(shí)間(exp),一旦過期必須重新獲取。此外,為了安全,很多應(yīng)用會(huì)使用 Refresh Token 機(jī)制,或者對(duì) Token 進(jìn)行加密處理(JWE),這大大增加了爬蟲模擬的復(fù)雜度。

第二章:Python 實(shí)戰(zhàn):模擬登錄與 Token 獲取

在掌握了理論基礎(chǔ)后,我們需要?jiǎng)邮植僮?。本章?jié)將使用 Python 的 requests 庫,演示如何從零開始獲取一個(gè) JWT Token。

2.1 準(zhǔn)備工作:分析目標(biāo) API

假設(shè)我們要爬取一個(gè)名為 “DataHub” 的虛構(gòu)平臺(tái)數(shù)據(jù)。首先,我們需要打開瀏覽器的開發(fā)者工具(F12),切換到 Network 面板,進(jìn)行一次真實(shí)的登錄操作。

觀察結(jié)果

  • 請(qǐng)求 URLhttps://api.datahub.com/v1/auth/login
  • 請(qǐng)求方法POST
  • 請(qǐng)求體(Payload){"username": "your_user", "password": "your_password"}

2.2 編寫獲取 Token 的 Python 代碼

利用 requests 庫,我們可以輕松模擬這個(gè)過程。

import requests

# 1. 定義登錄接口和憑證
login_url = "https://api.datahub.com/v1/auth/login"
headers = {
    "Content-Type": "application/json",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
}
payload = {
    "username": "your_username",
    "password": "your_password"
}

# 2. 發(fā)送登錄請(qǐng)求
try:
    response = requests.post(login_url, json=payload, headers=headers)
    
    # 檢查響應(yīng)狀態(tài)
    if response.status_code == 200:
        # 3. 解析響應(yīng)數(shù)據(jù)
        data = response.json()
        
        # 假設(shè)服務(wù)器返回的數(shù)據(jù)結(jié)構(gòu)如下:
        # {"code": 0, "msg": "success", "data": {"access_token": "eyJhbGciOiJIUz...", "refresh_token": "..."}}
        
        access_token = data.get("data", {}).get("access_token")
        
        if access_token:
            print(f"成功獲取 Token: {access_token[:20]}...")
        else:
            print("響應(yīng)中未找到 access_token 字段")
    else:
        print(f"登錄失敗,狀態(tài)碼: {response.status_code}, 原因: {response.text}")
        
except Exception as e:
    print(f"發(fā)生錯(cuò)誤: {e}")

2.3 常見登錄陷阱與應(yīng)對(duì)

  • 驗(yàn)證碼(Captcha):如果登錄接口帶有圖形驗(yàn)證碼,簡單的 requests 就失效了。此時(shí),你需要引入 OCR 庫(如 ddddocr)或者接入打碼平臺(tái)。
  • CSRF Token:部分老式網(wǎng)站在登錄時(shí)會(huì)要求攜帶一個(gè)隱藏的 CSRF Token。你需要先請(qǐng)求一次登錄頁,解析 HTML 獲取該 Token,再發(fā)起登錄。
  • 加密參數(shù):現(xiàn)在的前端為了安全,往往會(huì)將密碼進(jìn)行 JS 加密(如 RSA 或 AES)。你需要使用 Python 的 pycryptodome 庫復(fù)現(xiàn)該加密邏輯,或者直接使用 PyExecJS 執(zhí)行原生 JS 代碼。

第三章:帶著“通行證”出發(fā):在請(qǐng)求中注入 JWT

拿到 Token 后,萬里長征走完了一半?,F(xiàn)在我們需要將這個(gè) Token 應(yīng)用到后續(xù)的數(shù)據(jù)提交和獲取請(qǐng)求中。

3.1 構(gòu)造帶認(rèn)證的 Header

這是最關(guān)鍵的一步。絕大多數(shù) API 規(guī)范要求將 Token 放入 HTTP Header 的 Authorization 字段中,格式通常為 Bearer <token>。

import requests

# 假設(shè)我們已經(jīng)獲取到了 token
access_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

# 1. 構(gòu)造請(qǐng)求頭
headers = {
    "Authorization": f"Bearer {access_token}",
    "Content-Type": "application/json",
    "Accept": "application/json"
}

# 2. 訪問需要認(rèn)證的接口(例如:提交數(shù)據(jù)或獲取用戶信息)
target_url = "https://api.datahub.com/v1/user/profile"
# 或者是一個(gè) POST 提交接口
# target_url = "https://api.datahub.com/v1/data/submit"

try:
    # 發(fā)起 GET 請(qǐng)求獲取數(shù)據(jù)
    resp = requests.get(target_url, headers=headers)
    
    if resp.status_code == 200:
        print("數(shù)據(jù)獲取成功:", resp.json())
    elif resp.status_code == 401:
        print("錯(cuò)誤:Token 失效或未提供,請(qǐng)重新登錄!")
    elif resp.status_code == 403:
        print("錯(cuò)誤:Token 有效,但權(quán)限不足(Scope 不夠)!")
    else:
        print(f"未知錯(cuò)誤: {resp.status_code}")

except Exception as e:
    print(f"請(qǐng)求異常: {e}")

3.2 封裝為通用爬蟲類(Class)

為了代碼的復(fù)用性和可維護(hù)性,建議將 Token 管理封裝成一個(gè)類:

class JWTCrawler:
    def __init__(self, username, password):
        self.username = username
        self.password = password
        self.base_url = "https://api.datahub.com"
        self.token = None
        self.session = requests.Session() # 使用 Session 保持連接

    def login(self):
        """登錄并獲取 Token"""
        url = f"{self.base_url}/v1/auth/login"
        payload = {"username": self.username, "password": self.password}
        try:
            resp = self.session.post(url, json=payload)
            self.token = resp.json().get("data", {}).get("access_token")
            return True if self.token else False
        except Exception as e:
            print(f"登錄失敗: {e}")
            return False

    def request(self, method, endpoint, **kwargs):
        """通用請(qǐng)求方法,自動(dòng)注入 Token"""
        if not self.token:
            if not self.login():
                raise Exception("無法獲取有效 Token")
        
        url = f"{self.base_url}{endpoint}"
        headers = kwargs.get("headers", {})
        headers["Authorization"] = f"Bearer {self.token}"
        kwargs["headers"] = headers
        
        response = self.session.request(method, url, **kwargs)
        
        # 處理 Token 過期的情況(通常狀態(tài)碼為 401)
        if response.status_code == 401:
            print("Token 已過期,嘗試重新登錄...")
            if self.login():
                # 重新發(fā)起請(qǐng)求
                headers["Authorization"] = f"Bearer {self.token}"
                kwargs["headers"] = headers
                response = self.session.request(method, url, **kwargs)
            else:
                raise Exception("刷新 Token 失敗")
                
        return response

# 使用示例
# crawler = JWTCrawler("user", "pass")
# resp = crawler.request("GET", "/v1/data/list")
# print(resp.json())

第四章:進(jìn)階技巧與安全防御視角

作為一名資深的爬蟲開發(fā)者,不僅要學(xué)會(huì)攻,還要懂防。了解 JWT 的弱點(diǎn),能幫助我們應(yīng)對(duì)更復(fù)雜的反爬機(jī)制;了解防御策略,則能幫助我們開發(fā)更健壯的應(yīng)用。

4.1 應(yīng)對(duì)高級(jí)防御:Token 存儲(chǔ)與刷新

  • Refresh Token 機(jī)制:為了安全,很多應(yīng)用不會(huì)給 Access Token 很長的過期時(shí)間(如 15 分鐘)。此時(shí),服務(wù)器會(huì)同時(shí)返回一個(gè) Refresh Token(有效期 7 天)。當(dāng) Access Token 過期時(shí),客戶端應(yīng)使用 Refresh Token 去請(qǐng)求 /refresh 接口換取新的 Access Token。
  • 爬蟲應(yīng)對(duì):在 JWTCrawler 類中增加 refresh_token 字段,并在 request 方法捕獲 401 錯(cuò)誤后,優(yōu)先嘗試調(diào)用刷新接口,而不是直接重新登錄(避免頻繁觸發(fā)登錄風(fēng)控)。
  • HttpOnly Cookie:有些應(yīng)用雖然使用了 JWT,但為了防止 XSS 攻擊,會(huì)將 Token 存儲(chǔ)在 HttpOnly 的 Cookie 中,而不是 JS 可讀的 localStorage。這種情況下,requests 直接讀取 JS 變量是行不通的。
  • 爬蟲應(yīng)對(duì):使用 SeleniumPlaywright 等瀏覽器自動(dòng)化工具。先用瀏覽器自動(dòng)化工具完成登錄,然后通過 get_cookies() 提取 Token,再轉(zhuǎn)交給 requests 使用。

4.2 從防御者角度看 JWT 爬蟲

如果你是 API 的開發(fā)者,該如何防止他人通過模擬 JWT 爬取數(shù)據(jù)?

  1. 簽名算法選擇:嚴(yán)禁使用 None 算法。推薦使用 HS256(對(duì)稱)或 RS256(非對(duì)稱)。如果密鑰泄露,攻擊者可以偽造任何用戶的 Token。
  2. 增加黑名單機(jī)制:JWT 的特性是“一旦簽發(fā),無法撤回”。為了解決這個(gè)問題,可以在 Redis 中維護(hù)一個(gè) Token 黑名單(用戶注銷或修改密碼時(shí)將舊 Token 加入黑名單)。
  3. IP 與 User-Agent 綁定:在 Payload 中加入 IP 或設(shè)備指紋信息,并在驗(yàn)證時(shí)檢查。如果一個(gè) Token 突然在不同的 IP 下使用,判定為異常。
  4. 動(dòng)態(tài) Token(混淆 Token):像 WeChat 這樣的應(yīng)用,會(huì)使用動(dòng)態(tài) Token,每次請(qǐng)求后 Token 都會(huì)變化,或者使用加密的二進(jìn)制格式,大大增加了逆向難度。

4.3 總結(jié)

處理帶有 JWT 認(rèn)證的 Python 爬蟲,核心在于模擬“客戶端行為”。這不僅僅是發(fā)送 HTTP 請(qǐng)求,更是一個(gè)對(duì)認(rèn)證流程的逆向工程。

  • 初級(jí)階段:手動(dòng)抓包,硬編碼 Token。
  • 中級(jí)階段:編寫登錄腳本,自動(dòng)獲取并管理 Token。
  • 高級(jí)階段:處理 Token 過期刷新、應(yīng)對(duì)加密參數(shù)、結(jié)合瀏覽器自動(dòng)化工具解決復(fù)雜渲染問題。

隨著反爬技術(shù)的升級(jí),單純的 HTTP 請(qǐng)求越來越難以滿足需求,將 requests 的高效與 playwright 的渲染能力相結(jié)合,是未來爬蟲開發(fā)的必然趨勢。

以上就是使用Python優(yōu)雅地處理帶有JWT認(rèn)證的接口提交的詳細(xì)內(nèi)容,更多關(guān)于Python處理WT認(rèn)證接口提交的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • pandas.cut具體使用總結(jié)

    pandas.cut具體使用總結(jié)

    這篇文章主要介紹了pandas.cut具體使用總結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • 一篇文章弄懂Python關(guān)鍵字、標(biāo)識(shí)符和變量

    一篇文章弄懂Python關(guān)鍵字、標(biāo)識(shí)符和變量

    這篇文章主要給大家介紹了關(guān)于Python關(guān)鍵字、標(biāo)識(shí)符和變量的相關(guān)資料,Python關(guān)鍵詞是Python保留的具有特定含義的特殊詞語,用于執(zhí)行某些操作,Python標(biāo)識(shí)符是用戶定義的名稱,而變量是計(jì)算機(jī)內(nèi)存中的一塊區(qū)域,存儲(chǔ)對(duì)象的內(nèi)存地址,以便引用對(duì)象的值,需要的朋友可以參考下
    2021-07-07
  • 淺談python 線程池threadpool之實(shí)現(xiàn)

    淺談python 線程池threadpool之實(shí)現(xiàn)

    這篇文章主要介紹了淺談python 線程池threadpool之實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-11-11
  • 詳解Pandas之容易讓人混淆的行選擇和列選擇

    詳解Pandas之容易讓人混淆的行選擇和列選擇

    這篇文章主要介紹了詳解Pandas之容易讓人混淆的行選擇和列選擇,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • Python實(shí)現(xiàn)學(xué)生管理系統(tǒng)的代碼(JSON模塊)

    Python實(shí)現(xiàn)學(xué)生管理系統(tǒng)的代碼(JSON模塊)

    這篇文章主要介紹了Python實(shí)現(xiàn)學(xué)生管理系統(tǒng)的代碼(JSON模塊),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • python網(wǎng)絡(luò)編程實(shí)例簡析

    python網(wǎng)絡(luò)編程實(shí)例簡析

    這篇文章主要介紹了python網(wǎng)絡(luò)編程,有不錯(cuò)的借鑒價(jià)值,需要的朋友可以參考下
    2014-09-09
  • 利用Python獲取文件夾下所有文件實(shí)例代碼

    利用Python獲取文件夾下所有文件實(shí)例代碼

    在處理數(shù)據(jù)的過程中經(jīng)常需要遍歷文件夾,如果遠(yuǎn)程服務(wù)器的文件是分布式存儲(chǔ),遍歷需要更快的速度,下面這篇文章主要給大家介紹了關(guān)于利用Python獲取文件夾下所有文件的相關(guān)資料,需要的朋友可以參考下
    2023-01-01
  • python安裝cx_Oracle和wxPython的方法

    python安裝cx_Oracle和wxPython的方法

    這篇文章主要介紹了python安裝cx_Oracle和wxPython的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • python如何派生內(nèi)置不可變類型并修改實(shí)例化行為

    python如何派生內(nèi)置不可變類型并修改實(shí)例化行為

    這篇文章主要為大家詳細(xì)介紹了python如何派生內(nèi)置不可變類型并修改實(shí)例化行為,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • python操作日期和時(shí)間的方法

    python操作日期和時(shí)間的方法

    經(jīng)常獲得了一個(gè)用戶提交的當(dāng)前日期,我們需要以這個(gè)日期為依據(jù)返回它的前一天、后一天的日期或者轉(zhuǎn)換操作等。用Python可以非常簡單的解決這些關(guān)于日期計(jì)算的問題
    2014-03-03

最新評(píng)論

卓尼县| 昌都县| 宁津县| 乌兰县| 时尚| 磐安县| 六枝特区| 大新县| 高邮市| 姜堰市| 五峰| 建瓯市| 陆丰市| 竹溪县| 昌图县| 剑河县| 怀宁县| 满洲里市| 久治县| 政和县| 建水县| 兴国县| 牟定县| 芮城县| 邹城市| 沂南县| 罗江县| 时尚| 鲁山县| 海南省| 旬阳县| 旅游| 肥西县| 定州市| 牡丹江市| 博爱县| 天全县| 江北区| 丁青县| 江安县| 左贡县|